NDK .so Android调用JNI出错 java.lang.UnsatisfiedLinkError: No implementation found for的解决方案

抛异常:

NDK .so Android调用JNI出错 java.lang.UnsatisfiedLinkError: No implementation found for的解决方案_第1张图片

NDK c源码

#include 
JNIEXPORT jstring JNICALL
Java_com_example_fanenqian_ndk1_NDKtest_getString(JNIEnv *env, jclass type) {
    return (*env)->NewStringUTF(env, "this is NDK application");
}

JNI方法
public class NDKtest {
    public static native String getString();
    static {
        System.loadLibrary("ndk_mode");
    }
}


NDK .so Android调用JNI出错 java.lang.UnsatisfiedLinkError: No implementation found for的解决方案_第2张图片
很明显提示没有这个方法的实现
出现这个异常的原因是NDKtest类的包名一定要是com.example.fanenqian.ndk1,原因是JNI接口Java_com_example_fanenqian_ndk1_NDKtest_getString中,com_example_fanenqian_ndk1代表的是package name,NDKtest则是class name。所以该NDKtest包名必须是com_example_fanenqian_ndk1,类名是NDKtest,也就是说,我们.so中函数声明涉及到的package name和class name与调用它的package name和class name不符。因此我们要改变我们工程中的package name和class name。使其与.so文件中函数签名提示的一致,在这个类中加入native方法的声明。


JNI的命名规则

这里顺便说一下JNI的命名规则,对于传统的JNI编程来说,JNI方法跟Java类方法的名称之间有一定的对应关系,要遵循一定的命名规则,如下所示:

前缀: Java_
类的全限定名,用下划线进行分隔(_):com_oyp_jni_JniTest
方法名:getTestString
JNI函数指定第一个参数: JNIEnv *
JNI函数指定第二个参数: jobject
实际Java参数: jstring, jint ….
所以对于在Java类 com.oyp.jni.JniTest类的一个方法:
public native String getTestString (String oyp);
其对应的jni层的方法如下:
jstring Java_com_oyp_jni_JniTest_getTestString(JNIEnv * e, jobject clazz, jstring oyp);
如果不这样命名,当把动态库加载进DVM的时候,通过JNIEnv *指针去查找Java Native方法对应的JNI方法的时候,就会找不到了。 
注意,我们也可以利用函数注册的方法,将Java层的方法名跟JNI层的方法名的对应关系保存起来,注册到DVM中,就不需要这样的命名规范了。

你可能感兴趣的:(开发遇到的坑)