99

I'm trying to use the NDK with C++ and can't seem to get the method naming convention correct. my native method is as follows:

extern "C" {
JNIEXPORT void JNICALL Java_com_test_jnitest_SurfaceRenderer_drawFromJni
(JNIEnv* env, jclass c)
{
   //
}
}

with a header wrapped in extern "C" {} aslo.

Everything compiles fine, creates a .so file and copies to the libs folder under my project, but when I debug and run in Eclipse I keep getting a log cat message that of "no implementation found for native...". Is there something i'm missing as all the NDK examples are in C?

Thanks.

Khaled Alshaya
  • 94,250
  • 39
  • 176
  • 234
Patrick Kafka
  • 9,795
  • 3
  • 29
  • 44

11 Answers11

181

There are a couple of things that can lead to "no implementation found". One is getting the function prototype name wrong, another is failing to load the .so at all. Are you sure that System.loadLibrary() is being called before the method is used?

If you don't have a JNI_OnLoad function defined, you may want to create one and have it spit out a log message just to verify that the lib is getting pulled in successfully.

You already dodged the most common problem -- forgetting to use extern "C" -- so it's either the above or some slight misspelling. What does the Java declaration look like?

Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
fadden
  • 51,356
  • 5
  • 116
  • 166
  • 16
    Jesus! You saved me hours worth of work - upon reading this I had just remembered I had my loadLibrary call commented out... – zeboidlund May 01 '12 at 00:33
  • 11
    You saved me too! I quadruple-checked my function name and a couple of other things... but I forgot extern "C", and didn't even notice it in the question! – Qwertie May 25 '12 at 20:30
  • 1
    Now on the Android docs site: http://developer.android.com/training/articles/perf-jni.html#faq_ULE – fadden Dec 15 '12 at 00:49
  • An additional reason: Use LOCAL_WHOLE_STATIC_LIBRARIES instead of LOCAL_WHOLE_STATIC_LIBRARIES in android.mk. This stops the library from optimizing out unused API calls because the NDK cannot detect the use of the native bindings from java code. – John Twigg Oct 01 '13 at 18:35
  • Thank. My *.so libraries needed by two classes A & B. In ordinary sequences of the app, A will load the *.so and then only B (an activity class) will be executed. However, if one direct open B (after having the app stopped at B and running in background for long time), then this error will popup. After added the load libraries *.so to class B too, solved the issue. – Sany Liew Oct 09 '13 at 11:21
  • For me I was using C++ and functions were mangled. `extern` solved the problem – Peter Chaula Aug 06 '17 at 09:55
  • I missed extern "C" :) – Qadir Hussain Jul 04 '18 at 12:25
  • My jni method is `static`, I call the method before load *.so. awesome answer – bluesky Nov 27 '18 at 02:40
  • 3
    there is also one case nobody told about: you can't use '_' (underscores) in function names since underscores are intepreted as package separator. So , only camel case function names are possible – Nulik Dec 12 '18 at 21:27
  • 2
    @Nulik: you can use '_' if you [escape it](https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#resolving_native_method_names) as "_1". – fadden Dec 13 '18 at 05:53
21

An additional cause for this error: your undecorated native method name must not contain an underscore!

For example, I wanted to export a C function named AudioCapture_Ping(). Here is my export declaration in C:

JNI_EXPORT int Java_com_obsidian_mobilehashhost_MainActivity_AudioCapture_Ping(JNIEnv *pJniEnv, jobject object);  //Notice the underscore before Ping

Here was my Java class importing the function:

package com.obsidian.mobileaudiohashhost;
...
public class MainActivity extends Activity {
    private native int AudioCapture_Ping();  // FAILS
    ...

I could not get Android to dynamically link to my native method until I removed the underscore:

JNI_EXPORT int Java_com_obsidian_mobilehashhost_MainActivity_AudioCapturePing(JNIEnv *pJniEnv, jobject object); 

package com.obsidian.mobileaudiohashhost;
...
public class MainActivity extends Activity {
    private native int AudioCapturePing();  // THIS WORKS!
    ...
  • 9
    Occurrences of '_' in the Java-language declaration must be replaced with "_1" in the native declaration. See table 2-1 in http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/design.html . – fadden Jul 28 '17 at 16:05
  • 1
    So obvious, yet I didn't manage to figure it out on my own after several hours of debugging... Thanks, you saved me! – Georgi Atsev Aug 22 '17 at 13:54
  • @user1222021 I have a question, can we export cpp method for all activities in the project, do we need to specify the activity name in the method in .cpp file? – Kostadin Georgiev Jul 23 '19 at 07:38
16

I had the same problem, but to me the error was in the file Android.mk. I had it:

LOCAL_SRC_FILES := A.cpp
LOCAL_SRC_FILES := B.cpp 

but should have this:

LOCAL_SRC_FILES := A.cpp
LOCAL_SRC_FILES += B.cpp 

note the detail += instead :=

I hope that helps.

ademar111190
  • 14,215
  • 14
  • 85
  • 114
7

Called extern "C" as provided in the automatically-generated Studio example, but forgot to wrap the entire rest of the file, including following functions, in {} brackets. Only the first function worked.

DragonLord
  • 6,395
  • 4
  • 36
  • 38
5

An additional reason: Use LOCAL_WHOLE_STATIC_LIBRARIES instead of LOCAL_STATIC_LIBRARIES in android.mk. This stops the library from optimizing out unused API calls because the NDK cannot detect the use of the native bindings from java code.

John Twigg
  • 7,171
  • 4
  • 20
  • 20
  • 2
    Where is the difference in : "Use LOCAL_WHOLE_STATIC_LIBRARIES instead of LOCAL_STATIC_LIBRARIES in android.mk" – Josh Dec 14 '15 at 09:05
5

There is a cpp example under apps in ndk: https://github.com/android/ndk-samples/blob/master/hello-gl2/app/src/main/cpp/gl_code.cpp

Megha
  • 51
  • 1
3

If your package name includes _ character, you should write 1(one) after _ character as shown below:

MainActivity.java

package com.example.testcpp_2;

native-lib.cpp

JNICALL
Java_com_example_testcpp_12_MainActivity_stringFromJNI(
oiyio
  • 5,219
  • 4
  • 42
  • 54
3

Use javah (part of Java SDK). Its the tool exactly for this (generates .h header from .class file).

MartinH
  • 31
  • 1
1

I try all above solutions, but no one can solved my build error(jni java.lang.UnsatisfiedLinkError: No implementation found for...), at last I found that I forget to add my verify.cpp source file to CMakeList.txt add_library segement(verify.cpp is auto generate by Ctrl + Enter short key, maybe other file name), hope my response can help some one.

my build environment: Gradle + CMake

user2420449
  • 79
  • 1
  • 1
1

I Faced the same problem, and in my case the reason was that I had underscore in package name "RFID_Test" I renamed the Package and it worked. Thanks user1222021

Firas Shrourou
  • 625
  • 8
  • 19
-2

I faced the same problem twice. It happened, that the phone I tried to start the app from Android Studio used an API level that I haven't downloaded yet in Android Studio.

  1. Upgrade Android Studio to the latest version
  2. Download the necessary API from within Android Studio
Yuliwee
  • 327
  • 1
  • 11