使用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*返回