Android中关于JNI 的学习(一)对于JNIEnv的一些认识
作者:互联网
Android中关于JNI 的学习(一)对于JNIEnv的一些认识
Java 通过 JNI 机制调用 c/c++ 写的 native 程序。c/c++ 开发的 native 程序需要遵循一定的 JNI 规范,下面的例子就是一个 JNI 函数声明:
1 JNIEXPORT jstring JNICALL Java_com_clay_example_JNITest_getJNIString 2 (JNIEnv* env, jobject obj)
JVM 负责从Java Stack 转入 C/C++ Native Stack。当 Java 进入 JNI 调用,除了函数本身的参数(arg0),会多出两个参数:JNIEnv 指针和 jobject 指针。而我们在Java端定义这个方法的时候,是没有参数的,如下:
1 public native String printHello();
JNIEnv 指针是 JVM 创建的,用于 Native的 c/c++ 方法操纵 Java 执行栈中的数据,比如 Java Class, Java Method 等。
首先,JNI 对于JNIEnv 的使用, 提供了两种语法: c 语法以及 c++ 语法,如下:
c 语法:
1 jsize len = (*env)->GetArrayLength(env,array);
c++ 语法:
1 jsize len =env->GetArrayLength(array);
那么这个 JNIEnv 是干什么用的? 其实从这个参数的名称就可以看到,就是指 JNI 的运行环境,我觉得它就是对 Java 虚拟环境的一个引用,在 Android 中,就是指 Dalvik VM。 参考 jni.h 文件中关于 JNIEnv 的定义,如下(对于 C 和 C++,它的定义有点不一样):
1 struct _JNIEnv; 2 struct _JavaVM; 3 typedef const struct JNINativeInterface* C_JNIEnv; 4 5 #if defined(__cplusplus) 6 typedef _JNIEnv JNIEnv; 7 typedef _JavaVM JavaVM; 8 #else 9 typedef const struct JNINativeInterface* JNIEnv; 10 typedef const struct JNIInvokeInterface* JavaVM; 11 #endif
在 C 中,我们可以看到 JNIEnv 的类型就是 JNINativeInterface* ,是一个指针类型,那么在 C++中呢,_JNIEnv 是什么样的呢?
1 /* 2 * C++ object wrapper. 3 * 4 * This is usually overlaid on a C struct whose first element is a 5 * JNINativeInterface*. We rely somewhat on compiler behavior. 6 */ 7 struct _JNIEnv { 8 /* do not rename this; it does not seem to be entirely opaque */ 9 const struct JNINativeInterface* functions; 10 11 #if defined(__cplusplus) 12 13 jint GetVersion() 14 { return functions->GetVersion(this); }
而对于 C++ 来说, _JNIEnv 是一个结构体,里面包含了 JNINativeInterface* 的结构。
所以从这里也可以看到,对于 C 和 C++ 来说,它们引用 JNIEnv 中的方法是有一点不一样的。 总的来说,JNIEnv,不管是 C,还是 C++,其实关键都是 JNINativeInterface 的这个结构。
我们可以简单看一下 JNINativeInterface 结构的定义,如下:
1 /* 2 * Table of interface function pointers. 3 */ 4 struct JNINativeInterface { 5 void* reserved0; 6 void* reserved1; 7 void* reserved2; 8 void* reserved3; 9 10 jint (*GetVersion)(JNIEnv *); 11 12 jclass (*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*, 13 jsize); 14 jclass (*FindClass)(JNIEnv*, const char*); 15 16 jmethodID (*FromReflectedMethod)(JNIEnv*, jobject); 17 jfieldID (*FromReflectedField)(JNIEnv*, jobject); 18 /* spec doesn't show jboolean parameter */ 19 jobject (*ToReflectedMethod)(JNIEnv*, jclass, jmethodID, jboolean); 20 21 jclass (*GetSuperclass)(JNIEnv*, jclass); 22 jboolean (*IsAssignableFrom)(JNIEnv*, jclass, jclass); 23 24 /* spec doesn't show jboolean parameter */ 25 jobject (*ToReflectedField)(JNIEnv*, jclass, jfieldID, jboolean); 26 27 jint (*Throw)(JNIEnv*, jthrowable); 28 jint (*ThrowNew)(JNIEnv *, jclass, const char *); 29 jthrowable (*ExceptionOccurred)(JNIEnv*); 30 void (*ExceptionDescribe)(JNIEnv*); 31 void (*ExceptionClear)(JNIEnv*); 32 void (*FatalError)(JNIEnv*, const char*); 33 34 jint (*PushLocalFrame)(JNIEnv*, jint); 35 jobject (*PopLocalFrame)(JNIEnv*, jobject); 36 37 jobject (*NewGlobalRef)(JNIEnv*, jobject); 38 void (*DeleteGlobalRef)(JNIEnv*, jobject); 39 void (*DeleteLocalRef)(JNIEnv*, jobject); 40 jboolean (*IsSameObject)(JNIEnv*, jobject, jobject); 41 42 jobject (*NewLocalRef)(JNIEnv*, jobject); 43 jint (*EnsureLocalCapacity)(JNIEnv*, jint); 44 45 jobject (*AllocObject)(JNIEnv*, jclass); 46 jobject (*NewObject)(JNIEnv*, jclass, jmethodID, ...); 47 jobject (*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list); 48 jobject (*NewObjectA)(JNIEnv*, jclass, jmethodID, const jvalue*); 49 50 jclass (*GetObjectClass)(JNIEnv*, jobject); 51 jboolean (*IsInstanceOf)(JNIEnv*, jobject, jclass); 52 jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*); 53 54 jobject (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...); 55 jobject (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list); 56 jobject (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*); 57 jboolean (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...); 58 jboolean (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list); 59 jboolean (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*); 60 jbyte (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...); 61 jbyte (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list); 62 jbyte (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*); 63 jchar (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...); 64 jchar (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list); 65 jchar (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*); 66 jshort (*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...); 67 jshort (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list); 68 jshort (*CallShortMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*); 69 jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...); 70 jint (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list); 71 jint (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*); 72 jlong (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...); 73 jlong (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list); 74 jlong (*CallLongMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*); 75 jfloat (*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...); 76 jfloat (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list); 77 jfloat (*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*); 78 jdouble (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...); 79 jdouble (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list); 80 jdouble (*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*); 81 void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...); 82 void (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list); 83 void (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, const jvalue*); 84 85 jobject (*CallNonvirtualObjectMethod)(JNIEnv*, jobject, jclass, 86 jmethodID, ...); 87 jobject (*CallNonvirtualObjectMethodV)(JNIEnv*, jobject, jclass, 88 jmethodID, va_list); 89 jobject (*CallNonvirtualObjectMethodA)(JNIEnv*, jobject, jclass, 90 jmethodID, const jvalue*); 91 jboolean (*CallNonvirtualBooleanMethod)(JNIEnv*, jobject, jclass, 92 jmethodID, ...); 93 jboolean (*CallNonvirtualBooleanMethodV)(JNIEnv*, jobject, jclass, 94 jmethodID, va_list); 95 jboolean (*CallNonvirtualBooleanMethodA)(JNIEnv*, jobject, jclass, 96 jmethodID, const jvalue*); 97 jbyte (*CallNonvirtualByteMethod)(JNIEnv*, jobject, jclass, 98 jmethodID, ...); 99 jbyte (*CallNonvirtualByteMethodV)(JNIEnv*, jobject, jclass, 100 jmethodID, va_list); 101 jbyte (*CallNonvirtualByteMethodA)(JNIEnv*, jobject, jclass, 102 jmethodID, const jvalue*); 103 jchar (*CallNonvirtualCharMethod)(JNIEnv*, jobject, jclass, 104 jmethodID, ...); 105 jchar (*CallNonvirtualCharMethodV)(JNIEnv*, jobject, jclass, 106 jmethodID, va_list); 107 jchar (*CallNonvirtualCharMethodA)(JNIEnv*, jobject, jclass, 108 jmethodID, const jvalue*); 109 jshort (*CallNonvirtualShortMethod)(JNIEnv*, jobject, jclass, 110 jmethodID, ...); 111 jshort (*CallNonvirtualShortMethodV)(JNIEnv*, jobject, jclass, 112 jmethodID, va_list); 113 jshort (*CallNonvirtualShortMethodA)(JNIEnv*, jobject, jclass, 114 jmethodID, const jvalue*); 115 jint (*CallNonvirtualIntMethod)(JNIEnv*, jobject, jclass, 116 jmethodID, ...); 117 jint (*CallNonvirtualIntMethodV)(JNIEnv*, jobject, jclass, 118 jmethodID, va_list); 119 jint (*CallNonvirtualIntMethodA)(JNIEnv*, jobject, jclass, 120 jmethodID, const jvalue*); 121 jlong (*CallNonvirtualLongMethod)(JNIEnv*, jobject, jclass, 122 jmethodID, ...); 123 jlong (*CallNonvirtualLongMethodV)(JNIEnv*, jobject, jclass, 124 jmethodID, va_list); 125 jlong (*CallNonvirtualLongMethodA)(JNIEnv*, jobject, jclass, 126 jmethodID, const jvalue*); 127 jfloat (*CallNonvirtualFloatMethod)(JNIEnv*, jobject, jclass, 128 jmethodID, ...); 129 jfloat (*CallNonvirtualFloatMethodV)(JNIEnv*, jobject, jclass, 130 jmethodID, va_list); 131 jfloat (*CallNonvirtualFloatMethodA)(JNIEnv*, jobject, jclass, 132 jmethodID, const jvalue*); 133 jdouble (*CallNonvirtualDoubleMethod)(JNIEnv*, jobject, jclass, 134 jmethodID, ...); 135 jdouble (*CallNonvirtualDoubleMethodV)(JNIEnv*, jobject, jclass, 136 jmethodID, va_list); 137 jdouble (*CallNonvirtualDoubleMethodA)(JNIEnv*, jobject, jclass, 138 jmethodID, const jvalue*); 139 void (*CallNonvirtualVoidMethod)(JNIEnv*, jobject, jclass, 140 jmethodID, ...); 141 void (*CallNonvirtualVoidMethodV)(JNIEnv*, jobject, jclass, 142 jmethodID, va_list); 143 void (*CallNonvirtualVoidMethodA)(JNIEnv*, jobject, jclass, 144 jmethodID, const jvalue*); 145 146 jfieldID (*GetFieldID)(JNIEnv*, jclass, const char*, const char*); 147 148 jobject (*GetObjectField)(JNIEnv*, jobject, jfieldID); 149 jboolean (*GetBooleanField)(JNIEnv*, jobject, jfieldID); 150 jbyte (*GetByteField)(JNIEnv*, jobject, jfieldID); 151 jchar (*GetCharField)(JNIEnv*, jobject, jfieldID); 152 jshort (*GetShortField)(JNIEnv*, jobject, jfieldID); 153 jint (*GetIntField)(JNIEnv*, jobject, jfieldID); 154 jlong (*GetLongField)(JNIEnv*, jobject, jfieldID); 155 jfloat (*GetFloatField)(JNIEnv*, jobject, jfieldID); 156 jdouble (*GetDoubleField)(JNIEnv*, jobject, jfieldID); 157 158 void (*SetObjectField)(JNIEnv*, jobject, jfieldID, jobject); 159 void (*SetBooleanField)(JNIEnv*, jobject, jfieldID, jboolean); 160 void (*SetByteField)(JNIEnv*, jobject, jfieldID, jbyte); 161 void (*SetCharField)(JNIEnv*, jobject, jfieldID, jchar); 162 void (*SetShortField)(JNIEnv*, jobject, jfieldID, jshort); 163 void (*SetIntField)(JNIEnv*, jobject, jfieldID, jint); 164 void (*SetLongField)(JNIEnv*, jobject, jfieldID, jlong); 165 void (*SetFloatField)(JNIEnv*, jobject, jfieldID, jfloat); 166 void (*SetDoubleField)(JNIEnv*, jobject, jfieldID, jdouble); 167 168 jmethodID (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*); 169 170 jobject (*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, ...); 171 jobject (*CallStaticObjectMethodV)(JNIEnv*, jclass, jmethodID, va_list); 172 jobject (*CallStaticObjectMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*); 173 jboolean (*CallStaticBooleanMethod)(JNIEnv*, jclass, jmethodID, ...); 174 jboolean (*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID, 175 va_list); 176 jboolean (*CallStaticBooleanMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*); 177 jbyte (*CallStaticByteMethod)(JNIEnv*, jclass, jmethodID, ...); 178 jbyte (*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, va_list); 179 jbyte (*CallStaticByteMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*); 180 jchar (*CallStaticCharMethod)(JNIEnv*, jclass, jmethodID, ...); 181 jchar (*CallStaticCharMethodV)(JNIEnv*, jclass, jmethodID, va_list); 182 jchar (*CallStaticCharMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*); 183 jshort (*CallStaticShortMethod)(JNIEnv*, jclass, jmethodID, ...); 184 jshort (*CallStaticShortMethodV)(JNIEnv*, jclass, jmethodID, va_list); 185 jshort (*CallStaticShortMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*); 186 jint (*CallStaticIntMethod)(JNIEnv*, jclass, jmethodID, ...); 187 jint (*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID, va_list); 188 jint (*CallStaticIntMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*); 189 jlong (*CallStaticLongMethod)(JNIEnv*, jclass, jmethodID, ...); 190 jlong (*CallStaticLongMethodV)(JNIEnv*, jclass, jmethodID, va_list); 191 jlong (*CallStaticLongMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*); 192 jfloat (*CallStaticFloatMethod)(JNIEnv*, jclass, jmethodID, ...); 193 jfloat (*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list); 194 jfloat (*CallStaticFloatMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*); 195 jdouble (*CallStaticDoubleMethod)(JNIEnv*, jclass, jmethodID, ...); 196 jdouble (*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list); 197 jdouble (*CallStaticDoubleMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*); 198 void (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...); 199 void (*CallStaticVoidMethodV)(JNIEnv*, jclass, jmethodID, va_list); 200 void (*CallStaticVoidMethodA)(JNIEnv*, jclass, jmethodID, const jvalue*); 201 202 jfieldID (*GetStaticFieldID)(JNIEnv*, jclass, const char*, 203 const char*); 204 205 jobject (*GetStaticObjectField)(JNIEnv*, jclass, jfieldID); 206 jboolean (*GetStaticBooleanField)(JNIEnv*, jclass, jfieldID); 207 jbyte (*GetStaticByteField)(JNIEnv*, jclass, jfieldID); 208 jchar (*GetStaticCharField)(JNIEnv*, jclass, jfieldID); 209 jshort (*GetStaticShortField)(JNIEnv*, jclass, jfieldID); 210 jint (*GetStaticIntField)(JNIEnv*, jclass, jfieldID); 211 jlong (*GetStaticLongField)(JNIEnv*, jclass, jfieldID); 212 jfloat (*GetStaticFloatField)(JNIEnv*, jclass, jfieldID); 213 jdouble (*GetStaticDoubleField)(JNIEnv*, jclass, jfieldID); 214 215 void (*SetStaticObjectField)(JNIEnv*, jclass, jfieldID, jobject); 216 void (*SetStaticBooleanField)(JNIEnv*, jclass, jfieldID, jboolean); 217 void (*SetStaticByteField)(JNIEnv*, jclass, jfieldID, jbyte); 218 void (*SetStaticCharField)(JNIEnv*, jclass, jfieldID, jchar); 219 void (*SetStaticShortField)(JNIEnv*, jclass, jfieldID, jshort); 220 void (*SetStaticIntField)(JNIEnv*, jclass, jfieldID, jint); 221 void (*SetStaticLongField)(JNIEnv*, jclass, jfieldID, jlong); 222 void (*SetStaticFloatField)(JNIEnv*, jclass, jfieldID, jfloat); 223 void (*SetStaticDoubleField)(JNIEnv*, jclass, jfieldID, jdouble); 224 225 jstring (*NewString)(JNIEnv*, const jchar*, jsize); 226 jsize (*GetStringLength)(JNIEnv*, jstring); 227 const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*); 228 void (*ReleaseStringChars)(JNIEnv*, jstring, const jchar*); 229 jstring (*NewStringUTF)(JNIEnv*, const char*); 230 jsize (*GetStringUTFLength)(JNIEnv*, jstring); 231 /* JNI spec says this returns const jbyte*, but that's inconsistent */ 232 const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*); 233 void (*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*); 234 jsize (*GetArrayLength)(JNIEnv*, jarray); 235 jobjectArray (*NewObjectArray)(JNIEnv*, jsize, jclass, jobject); 236 jobject (*GetObjectArrayElement)(JNIEnv*, jobjectArray, jsize); 237 void (*SetObjectArrayElement)(JNIEnv*, jobjectArray, jsize, jobject); 238 239 jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize); 240 jbyteArray (*NewByteArray)(JNIEnv*, jsize); 241 jcharArray (*NewCharArray)(JNIEnv*, jsize); 242 jshortArray (*NewShortArray)(JNIEnv*, jsize); 243 jintArray (*NewIntArray)(JNIEnv*, jsize); 244 jlongArray (*NewLongArray)(JNIEnv*, jsize); 245 jfloatArray (*NewFloatArray)(JNIEnv*, jsize); 246 jdoubleArray (*NewDoubleArray)(JNIEnv*, jsize); 247 248 jboolean* (*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*); 249 jbyte* (*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*); 250 jchar* (*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*); 251 jshort* (*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*); 252 jint* (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*); 253 jlong* (*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*); 254 jfloat* (*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*); 255 jdouble* (*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*); 256 257 void (*ReleaseBooleanArrayElements)(JNIEnv*, jbooleanArray, 258 jboolean*, jint); 259 void (*ReleaseByteArrayElements)(JNIEnv*, jbyteArray, 260 jbyte*, jint); 261 void (*ReleaseCharArrayElements)(JNIEnv*, jcharArray, 262 jchar*, jint); 263 void (*ReleaseShortArrayElements)(JNIEnv*, jshortArray, 264 jshort*, jint); 265 void (*ReleaseIntArrayElements)(JNIEnv*, jintArray, 266 jint*, jint); 267 void (*ReleaseLongArrayElements)(JNIEnv*, jlongArray, 268 jlong*, jint); 269 void (*ReleaseFloatArrayElements)(JNIEnv*, jfloatArray, 270 jfloat*, jint); 271 void (*ReleaseDoubleArrayElements)(JNIEnv*, jdoubleArray, 272 jdouble*, jint); 273 274 void (*GetBooleanArrayRegion)(JNIEnv*, jbooleanArray, 275 jsize, jsize, jboolean*); 276 void (*GetByteArrayRegion)(JNIEnv*, jbyteArray, 277 jsize, jsize, jbyte*); 278 void (*GetCharArrayRegion)(JNIEnv*, jcharArray, 279 jsize, jsize, jchar*); 280 void (*GetShortArrayRegion)(JNIEnv*, jshortArray, 281 jsize, jsize, jshort*); 282 void (*GetIntArrayRegion)(JNIEnv*, jintArray, 283 jsize, jsize, jint*); 284 void (*GetLongArrayRegion)(JNIEnv*, jlongArray, 285 jsize, jsize, jlong*); 286 void (*GetFloatArrayRegion)(JNIEnv*, jfloatArray, 287 jsize, jsize, jfloat*); 288 void (*GetDoubleArrayRegion)(JNIEnv*, jdoubleArray, 289 jsize, jsize, jdouble*); 290 291 /* spec shows these without const; some jni.h do, some don't */ 292 void (*SetBooleanArrayRegion)(JNIEnv*, jbooleanArray, 293 jsize, jsize, const jboolean*); 294 void (*SetByteArrayRegion)(JNIEnv*, jbyteArray, 295 jsize, jsize, const jbyte*); 296 void (*SetCharArrayRegion)(JNIEnv*, jcharArray, 297 jsize, jsize, const jchar*); 298 void (*SetShortArrayRegion)(JNIEnv*, jshortArray, 299 jsize, jsize, const jshort*); 300 void (*SetIntArrayRegion)(JNIEnv*, jintArray, 301 jsize, jsize, const jint*); 302 void (*SetLongArrayRegion)(JNIEnv*, jlongArray, 303 jsize, jsize, const jlong*); 304 void (*SetFloatArrayRegion)(JNIEnv*, jfloatArray, 305 jsize, jsize, const jfloat*); 306 void (*SetDoubleArrayRegion)(JNIEnv*, jdoubleArray, 307 jsize, jsize, const jdouble*); 308 309 jint (*RegisterNatives)(JNIEnv*, jclass, const JNINativeMethod*, 310 jint); 311 jint (*UnregisterNatives)(JNIEnv*, jclass); 312 jint (*MonitorEnter)(JNIEnv*, jobject); 313 jint (*MonitorExit)(JNIEnv*, jobject); 314 jint (*GetJavaVM)(JNIEnv*, JavaVM**); 315 316 void (*GetStringRegion)(JNIEnv*, jstring, jsize, jsize, jchar*); 317 void (*GetStringUTFRegion)(JNIEnv*, jstring, jsize, jsize, char*); 318 319 void* (*GetPrimitiveArrayCritical)(JNIEnv*, jarray, jboolean*); 320 void (*ReleasePrimitiveArrayCritical)(JNIEnv*, jarray, void*, jint); 321 322 const jchar* (*GetStringCritical)(JNIEnv*, jstring, jboolean*); 323 void (*ReleaseStringCritical)(JNIEnv*, jstring, const jchar*); 324 325 jweak (*NewWeakGlobalRef)(JNIEnv*, jobject); 326 void (*DeleteWeakGlobalRef)(JNIEnv*, jweak); 327 328 jboolean (*ExceptionCheck)(JNIEnv*); 329 330 jobject (*NewDirectByteBuffer)(JNIEnv*, void*, jlong); 331 void* (*GetDirectBufferAddress)(JNIEnv*, jobject); 332 jlong (*GetDirectBufferCapacity)(JNIEnv*, jobject); 333 334 /* added in JNI 1.6 */ 335 jobjectRefType (*GetObjectRefType)(JNIEnv*, jobject); 336 };
可以看到在它其中定义了很多的函数指针,而通过这些定义,JNI层其实就获得了对DVM的引用,通过定义的这些函数指针,可以定位到虚拟机中的 JNI 函数表,从而实现JNI层在DVM中的函数调用。 所以,可以这样理解,其实JNIEnv,就是对DVM运行环境中C/C++函数的一个引用,而也正因为此,当C/C++想要在DVM中调用函数的时候,由于其是在DVM的环境中,所以它们必须通过JNIEnv* 这个参数来获得这些方法,之后才能够使用。 那么这个JNIEnv是什么时候产生的呢? 当Android中第一个Java线程要调用本地的C/C++代码的时候,DVM就会为该线程产生一个JNIEnv*的指针。而每一个线程在和C/C++互相调用的时候,其对应的JNIEnv 也是相互独立。 嗯,结束。
标签:const,jobject,JNIEnv,void,jmethodID,JNI,jclass,Android 来源: https://www.cnblogs.com/Reverse-xiaoyu/p/14117991.html