Jni 可以通过JNIEnv提供的方法,对传过来的Java数组进行相应的操作。它提供了两种函数:一种是操作Java的简单型数组的,另一种是操作对象类型数组的。
操作Java的简单型数组
因为速度的原因,简单类型的Java数组,会作为指向本地类型的指针暴露给本地代码调用。因此,它们能作为常规的数组存取。这个指针是指向实际的Java数组或者Java数组的拷贝的指针。另外,数组的布置保证匹配本地类型。
在C/C++中,jintArray 不能用下标对其进行直接存取,必须用到JNI中提供的接口函数进行操作。 为了存取Java简单类型的数组,就要要使用GetXXXArrayElements函数(见表),XXX代表了数组的类型。这个函数把Java数组看成参数,返回一个指向对应的本地类型的数组的指针。
函数 | Java 数组类型 | 本地类型 |
GetBooleanArrayElements | jbooleanArray | jboolean |
GetByteArrayElements | jbyteArray | jbyte |
GetCharArrayElements | jcharArray | jchar |
GetShortArrayElements | jshortArray | jshort |
GetIntArrayElements | jintArray | jint |
GetLongArrayElements | jlongArray | jlong |
GetFloatArrayElements | jfloatArray | jfloat |
GetDoubleArrayElements | jdoubleArray | jdouble |
JNIEXPORT jint JNICALL Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr) { jint *carr; carr = (*env)->GetIntArrayElements(env, arr, false); //获得Java数组arr的引用的指针 if(carr == NULL) { return 0; /* exception occurred */ } jint sum = 0; for(int i=0; i<10; i++) { sum += carr[i]; } (*env)->ReleaseIntArrayElements(env, arr, carr, 0); return sum; }
操作对象类型数组
在C/C++代码中,int类型的数组对应JNI中的jintArray,而类似字符串数组这种类型的,在Jni里对应的使用 jobjectArray 来声明,下面是存取访问 jobjectArray 的方法简介:
GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index) array: a reference to the java.lang.Object array from which the element will be accessed. index: the array index 功能:返回对应索引值的object.返回的是一个数组元素的值。 SetObjectArrayElement(JNIEnv* env, jobjectArray array, jsize index, jobject value) array: a reference to an array whose element will be accessed. index: index of the array element to be accessed. value: the new value of the array element. 功能:用来设置对应索引元素的值。
Get/SetXXXArrayRegion函数说明
GetIntArrayRegion(array,jsize start,jsize len,*buf) array:a reference to an array whose elements are to be copied. start:the starting index of the array elements to be copied. len: the number of elements to be copied. buf: the destination buffer. 功能:把jintArray中的元素复制到buffer中。 SetIntArrayRegion(array,jsize start,jsize len,*buf) array:a reference to a primitive array to which the elements to be copied. start:the starting index in the primitive array. len:the number of elements to be copied. buf:the source buffer. 功能:把buf中的元素copy到jintArray中去。
使用SetXXXArrayRegion与GetXXXArrayRegion就是以复制的方式设置与取出Array数组中的某个值。
关于二维数组和String数组
在Jni中,二维数组和String数组都被视为object数组,因为Array和String被视为object。下面例子实现了构造并返回一个二维int数组:
JNIEXPORT jobjectArray JNICALL Java_ObjectArrayTest_initInt2DArray(JNIEnv *env, jclass cls, int size) { jobjectArray result; jclass intArrCls = (*env)->FindClass(env, "[I"); //int数组的class result = (*env)->NewObjectArray(env, size, intArrCls, NULL); //二维int数组的实例 for (int i = 0; i < size; i++) { //初始化 jint tmp[256]; /* make sure it is large enough! */ for(int j = 0; j < size; j++) { tmp[j] = i + j; } jintArray iarr = (*env)->NewIntArray(env, size); (*env)->SetIntArrayRegion(env, iarr, 0, size, tmp); //将tmp复制到iarr中 (*env)->SetObjectArrayElement(env, result, i, iarr); (*env)->DeleteLocalRef(env, iarr); } return result; }
最后得特别说明一下,当你使用对数组进行访问后,要确保调用相应的ReleaseXXXArrayElements函数,参数是对应Java数组和GetXXXArrayElements返回的指针,如果必要的话,这个释放函数会复制你做的任何变化(这样它们就反射到java数组),然后释放所有相关的资源,避免发生内存泄漏。
本文转自Zhiweiofli's Blog,转载请注明出处,谢谢。
相关推荐
Android NDK 开发教程 三 Hello JNI 示例
Android NDK 开发教程 二 概述
该资源包含了一个用android实现的androidndk文档,简单易懂!
详细介绍了在eclipse中android项目下c/c++代码的自动编译,和在eclipse中用ant生成ndk需要的jni头文件,加速ndk的开发,因为是原创,费了不少心力和时间,所以设了6分,有人反映太贵了,现在调成3分,这下大家满意了...
android NDK 开发指南 android NDK 开发指南 android NDK 开发指南 android NDK 开发指南
android ndk 开发入门小例子。 博客地址http://blog.csdn.net/u014702653/article/details/51861013
Android NDK 开发的官方文档 (android ndk dev guide)。 阅读文档请点击documentation.html。
android ndk 开发总结,总结android ndk开发过程中的经验!
Android NDK开发的环境配置以及例子说明开发过程
《Android NDK 开发教程 - v1.0》
Android NDK开发PPT,包括Android NDK的概念及用途、Android NDK编译环境的建立与配置和Android NDK的开发
android NDK流程开发 移动开发
该资源教程,是在eclipse下实现的androidndk开发的文档,简单易懂,手把手教程!
ubuntu Android NDK开发环境的搭建
入门的NDK学习文档,很适合刚学android的同学
Android NDK基础知识,看完一定会对NDK开发有很大的收获!
Android开发之NDK入门 想要的速度 Android开发者必过的一关
Android NDK 开发时需要的 常用的JNI API
Android NDK Game Development Cookbook A systematic guide consisting of over 70 recipes which focus on helping you build portable mobile games and aims to enhance your game development skills with ...
Android NDK开发示例,用于学习Android的本地开发,对于初学者来说是很好的例子!