原生方法的强制参数
原生方法带两个参数:
JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_stringFromJNI(JNIEnv *, jobject)
1、JNIEnv 是指向可用 JNI 函数表的接口指针。
原生代码通过 JNIEnv 接口指针提供的各种函数来使用虚拟机的功能。JNIEnv 是一个指向线程-局部数据的指针,而线程-局部数据中包含指向函数表的指针。实现原生方法的函数将 JNIEnv 接口指针作为它们的第一个参数。
注意:传递给每一个原生方法调用的 JNIEnv 接口指针在与方法调用相关的线程中也有效,但是它不能被缓存以及被其它线程使用。
原生代码是 C 与 原生代码是 C++ 其调用 JNI 函数的语法不同:
在 C 代码中,JNIEnv 是指向 JNINativeInterface 结构的指针,为了访问任何一个 JNI 函数,该指针需要首先被解引用。因为 C 代码中的 JNI 函数不了解当前的 JNI 环境,JNIEnv 实例应该作为第一个参数传递给每一个 JNI 函数调用者,调用格式如下:
return (*env)->NewStringUTF(env, "Hello from JNI !");
在 C++ 代码中,JNIEnv 实际上是 C++ 类实例,JNI 函数以成员函数的形式存在。因为 JNI 方法已经访问了当前的 JNI 环境,因此 JNI 方法调用不要求 JNIEnv 实例作参数。在 C++ 中,完成同样功能的调用代码格式如下:
return env->NewStringUTF("Hello from JNI !");
2、jobject 是 HelloJni 类实例的 Java 对象引用。
java 程序设计语言有两类方法:实例方法和静态方法。
实例方法与类实例相关,它们只能在类实例中调用,静态方法不与类实例相关,它们可以在静态上下文直接调用。静态方法和实例方法均可以声明为原生的,可以通过 JNI 技术以原生代码的形式提供它们的实现,原生实例方法通过第二个参数获取实例引用,该参数是 jobject 类型的,如:
JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_stringFromJNI(JNIEnv * env, jobject thiz)
因为静态方法没有与实例绑定,因此通过第二个参数获取类引用而不是实例引用,第二个参数是 jclass 值类型的,如:
JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_stringFromJNI(JNIEnv * env, jclass clazz)
【参考文献】
1、《Android C++ 高级编程——使用NDK》

浙公网安备 33010602011771号