Array Operations(操作数组)
java 中的数组被JNI作为一个引用类型处理,JNI提供了必要的函数访问和操作java中的数组
New Array(创建数组)
新的数组实例能够通过使用New<Type>Array函数从本地代码中进行实例化,Type可以是Int ,Char,Boolean,等数据类型,例入NewIntArray.如下所示,当调用这些函数的时候数组的大小应该作为一个参数被提供。
jintArray javaArray;
javaArray = (*env)->NewIntArray(env,10);
if ( 0 != javaArray)
{
/*你现在能够使用这个数组*/
}
与NewString 函数一样,在内存溢出的情况下,New<Type>Array函数将返回NULL目的是为了通知本地化代码一个异常已经被抛出并让本地化代码停止运行。
Accessing the Array(访问数组元素)
JNI提供了两种访问java数组的方法。代码能够得到这个数组的一个C数组拷贝或者直接得到一个指向该java数组的指针。
Operating on a Copy (操作一个拷贝)
Get<Type>ArrayRegion函数拷贝原生的java数组到给定的c数组,如下所示:
jint nativeArray[10];
(*env)->GetIntArrayRegion(env,javaArray,0,10,nativeArray);
本地化代码能够使用和修改这个c数组的元素,当本地化代码想要提交改变后的c数组到java数组,可以使用set<Type>ArrayRegion函数拷贝c数组到java数组,如下所示:
(*env)->SetIntArrayRegion(env,javaArray,0,10,nativeArray);
当数组很大时通过一个c的拷贝数组来操作java数组会引起性能问题,在这种情况下本地化代码应该仅仅是获得或设置这个数组的一小块元素区域而不是整个数组。此外JNI还提供了另外一组函数目的是为了能够直接得到这个数组的指针来代替他的一个拷贝。
Operation on Direct Pointer(直接在指针上进行操作)
Get<Type>ArrayElements函数允许本地化代码直接得到数组元素的一个指针,如下面的代码所示,这个函数带有三个参数,一个pass-by-reference名为isCopy 的输出参数他允许调用者决定是否要返回一个指向C数组的拷贝或是堆中固有的数组。
jint* nativeDirectArray;
jboolean isCopy;
nativeDirecArray = (*env)->GetIntArrayElements(env, javaArray, &isCopy);
因为这个数组能够像原生的C数组一样操作数组,所以JNI没有为其提供set方法。当操作完成后JNI要求释放指针。否则会导致内存泄漏。JNI提供Release<Type>ArrayElements函数来启用本地化代码释放和返回此c数组。如下所示:
(*env)->ReleaseIntArrayElements(env, javaArray, nativeDirectArray, 0);
这个函数的第四个参数是释放模式,如下表:
Release Mode | Action |
0 | Copy back the content and free the native array.(拷贝并返回数组内容并且释放本地数组) |
JNI_COMMIT | Copy back the content but do not free the native array. (拷贝并返回数组内容但不释放本 地数组) This can be used for periodically updating a Java array.(可用于定期更新java数组) |
JNI_ABORT | Free the native array without copying its content.(释放本地数组但不拷贝他的内容) |