🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
之前使用GetIntArrayRegion函数的示例会将int数组中的所有元素拷贝到一个C缓冲区中。第三个参数是数组的起始下表,第四个参数是需要拷贝的元素个数。只有当数组元素被拷贝到C数组中之后,我们才能在原生代码中访问它。在我们的示例中数组的长度很明确,就是10,所以我们就没有进行必要的异常检查。 JNI支持另一个函数SetIntArrayRegion允许原生代码修改int数组中的元素。其他的基础数据类型也是被支持的(如boolean,short和float). JNI支持一组函数Get/Release<Type>ArrayElements函数(包括像Get/ReleaseIntArrayElements)允许原生代码获取一个指向原始类型数组的指针。由于底层的垃圾回收机制不支持内存追溯机制,所以虚拟机可能会返回原始数组的一份拷贝。我们可以使用GetIntArrayElements重写3.3.1节的示例。 ~~~ /* * Class: IntArray * Method: sumArray * Signature: ([I)I */ JNIEXPORT jint JNICALL Java_IntArray_sumArray (JNIEnv * env, jobject obj, jintArray arr) { jint i, sum = 0; jint* carr = (*env)->GetIntArrayElements(env, arr, NULL); if(!carr) { return 0; /* exception occurred */ } for (int i =0; i < 10; i ++){ sum += carr[i]; } (*env)->ReleaseIntArrayElements(env, arr, carr, 0); return sum; } ~~~ 另有一个GetArrayLength函数返回基础类型或对象数组中的元素个数。数组的长度是固定不可变的,数组第一次分配的时候它的长度就被决定了。 Java 2 SDK release 1.2 引入了Get/ReleasePrimitiveArrayCritical函数。这些函数允许虚拟机在原生代码访问基础类型数组的时候禁止垃圾回收。在使用这组函数的时候,开发者必须像Get/ReleaseStringCritical那样小心。在Get/ReleasePrimitiveArrayCritical函数中,原生代码必须不能调用任何JNI函数或者执行任何阻塞操作,那可能引起应用程序死锁。