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,转载请注明出处,谢谢。


更多相关文章

  1. Android中关于JNI 的学习(一)对于JNIEnv的一些认识
  2. Android(安卓)Studio3.0开发JNI流程------JNI接口函数和指针
  3. Mac下使用Eclipse实现Android中调用C/C++(NDK)基础详细教程
  4. android 安全讲座第五层(三) android so注入的研究
  5. Android(安卓)OpenGLES2.0(七)——着色器语言GLSL
  6. 探究Android的多分辨率支持以及各种类型图标尺寸大小
  7. 在android中使用Get方式提交数据
  8. 【Android】Android中WebView实现Java与JS交互
  9. android回调机制总结

随机推荐

  1. Android 开发者从0到1发布一个微信小程序
  2. Bottomley在Linux大会的发言:Android,forki
  3. Ubuntu下android学习——(2)Android系统构
  4. 微软一年通过Android获得几十亿美元收入,
  5. Crosswalk 集成到 Android(安卓)Studio
  6. 服务器基于PHP CodeIgniter,Android基于Vo
  7. Android(安卓)SharedPreferences用法及程
  8. Android官方离线文档(API文档)打开速度慢的
  9. Android中Cursor关闭的问题
  10. Android工程 引用另外一个Android工程(类