使用C语言调用jni的时候,需要和java的环境对象和虚拟机对象交互。它们的C语言定义如下。
typedef const struct JNINativeInterface* JNIEnv;
typedef const struct JNIInvokeInterface* JavaVM;
可以看到,JNIEnv和JavaVM是一个指针类型。其结构体包含了很多我们需要用的函数指针:
jobject (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...);
jobject (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jobject (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
jboolean (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...);
由于C语言中没有this指针,所以这里所有的函数第一个参数,都是相当于this对象传入调用者。那么,一般我们通过如下函数,获得JNIEnv变量,然后使用。
JNIEnv* envPtr = NULL;
(*nativeActivity->vm)->AttachCurrentThread(nativeActivity->vm, &envPtr, NULL);
(*envPtr)->FindClass(envPtr, "android/app/NativeActivity");
AttachCurrentThread函数,需要一个JNIEnv**二级指针变量,然后把JNIEnv*返回

在C语言调用JNI时,与Java环境和虚拟机的交互涉及JNIEnv指针。AttachCurrentThread函数返回的JNIEnv*可能是独立内存或连续内存一部分,其具体性质由库函数实现者掌控。虽然可以解引用后直接使用,但这样做可能丢失了对特定内存区域的访问权限。因此,必须传递AttachCurrentThread返回的地址给后续的JNIEnv函数,如FindClass,因为这些函数需要原始地址来访问关联内存数据。
9678

被折叠的 条评论
为什么被折叠?



