NDK开发之数组操作
2015-09-04 21:02
323 查看
JNI把Java数组当作引用类型来处理,JNI提供了必要的函数来访问和处理Java数组。
下面一个一个来看。
1.创建数组
我们可以使用NewArray函数在原生代码中创建数组实例,其中可以是Int、Char、和Boolean等,例如NewIntArray,使用这些函数时应该以参数的形式给出数组的大小。看下面一段代码:
先定义一个jintArray数组,然后定义一个jint数组,将jint数组的内容提交给jintArray,然后返回jintArray。
与NewString函数一样,在内存溢出的情况下,NewArray函数将返回NULL以通知原生代码虚拟机中有异常抛出,这样原生代码就会停止运行。
2.访问数组元素
JNI提供两种访问Java数组元素的方法,可以将Java数组复制为C数组,或者让JNI提供直接指向数组元素的指针。下面将对这两种方法分别介绍。
2.1对副本的操作
我们可以将一个Java数组复制成一个C数组,然后对这个数组进行操作。
看下面一段代码,Java传进来一个数组,我们计算数组元素之和然后返回。
原生代码可以像使用普通的C数组一样使用和修改数组元素。当原生代码相将所做的修改提交给Java数组时,可以使用SetArrayRegion函数将C数组复制回Java数组中。
看下面代码,我们将Java传进来的数组中的每个元素加1,然后再把修改后的数组返回。
2.2对直接指针的操作
原生代码可以用GetArrayElements函数获取指向数组元素的直接指针。第三个参数和我们在上篇博文中提到的一样,它是一个可选参数,该可选参数的名称为isCopy,让调用者确定返回的C字符串地址指向副本还是指向堆中的固定对象。
因为可以像普通的C数组一样访问和处理数组元素,因此JNI没有提供访问和处理元素的方法,JNI要求原生代码用完这些指针必须立刻释放,否则会出现内存溢出问题,原生代码可以使用JNI提供的ReleaseArrayElements函数来释放GetArrayElements函数返回的C数组。该函数有四个参数,第四个是释放模式,有以下三种。
这次我们用C做个简单的乘法,Java传进来一个数组,对该数组中元素求积之后返回。
好了,关于数组操作就说这么多,有问题欢迎留言讨论。
下面一个一个来看。
1.创建数组
我们可以使用NewArray函数在原生代码中创建数组实例,其中可以是Int、Char、和Boolean等,例如NewIntArray,使用这些函数时应该以参数的形式给出数组的大小。看下面一段代码:
先定义一个jintArray数组,然后定义一个jint数组,将jint数组的内容提交给jintArray,然后返回jintArray。
jintArray Java_com_example_jni_MainActivity_getIntArray(JNIEnv* env, jobject thiz) { jintArray javaArray; jint nativeArr[3] = {21,22,23}; javaArray = (*env)->NewIntArray(env,3); (*env)->SetIntArrayRegion(env,javaArray,0,3,nativeArr); return javaArray; }
与NewString函数一样,在内存溢出的情况下,NewArray函数将返回NULL以通知原生代码虚拟机中有异常抛出,这样原生代码就会停止运行。
2.访问数组元素
JNI提供两种访问Java数组元素的方法,可以将Java数组复制为C数组,或者让JNI提供直接指向数组元素的指针。下面将对这两种方法分别介绍。
2.1对副本的操作
我们可以将一个Java数组复制成一个C数组,然后对这个数组进行操作。
看下面一段代码,Java传进来一个数组,我们计算数组元素之和然后返回。
jint Java_com_example_jni_MainActivity_getSum(JNIEnv* env, jobject thiz,jintArray javaArray) { //获得Java传递进来数组的长度 jsize length = (*env)->GetArrayLength(env,javaArray); //定义一个C数组 jint nativeArr[length]; jint sum = 0; //将Java数组区复制到C数组中 (*env)->GetIntArrayRegion(env,javaArray,0,length,nativeArr); int i; //求和 for(i=0;i<length;i++){ sum+=nativeArr[i]; } return sum; }
原生代码可以像使用普通的C数组一样使用和修改数组元素。当原生代码相将所做的修改提交给Java数组时,可以使用SetArrayRegion函数将C数组复制回Java数组中。
看下面代码,我们将Java传进来的数组中的每个元素加1,然后再把修改后的数组返回。
jintArray Java_com_example_jni_MainActivity_arrAdd1(JNIEnv* env, jobject thiz,jintArray javaArray) { //获得Java传递进来数组的长度 jsize length = (*env)->GetArrayLength(env,javaArray); //定义一个C数组 //将Java数组区复制到C数组中 jint nativeArr[length]; (*env)->GetIntArrayRegion(env,javaArray,0,length,nativeArr); int i; //修改元素的值 for(i=0;i<length;i++){ nativeArr[i]=nativeArr[i]+1; } //从C数组向Java数组提交所做的修改 (*env)->SetIntArrayRegion(env,javaArray,0,length,nativeArr); return javaArray; }
2.2对直接指针的操作
原生代码可以用GetArrayElements函数获取指向数组元素的直接指针。第三个参数和我们在上篇博文中提到的一样,它是一个可选参数,该可选参数的名称为isCopy,让调用者确定返回的C字符串地址指向副本还是指向堆中的固定对象。
因为可以像普通的C数组一样访问和处理数组元素,因此JNI没有提供访问和处理元素的方法,JNI要求原生代码用完这些指针必须立刻释放,否则会出现内存溢出问题,原生代码可以使用JNI提供的ReleaseArrayElements函数来释放GetArrayElements函数返回的C数组。该函数有四个参数,第四个是释放模式,有以下三种。
0:将内容复制回来并释放原生数组 JNI_COMMIT:将内容复制回来但是不释放原生数组,一般用于周期性的更新一个Java数组。 JNI_ABORT释放原生数组但是不将内容复制回来。
这次我们用C做个简单的乘法,Java传进来一个数组,对该数组中元素求积之后返回。
jint Java_com_example_jni_MainActivity_multiplication(JNIEnv* env,jobject thiz,jintArray javaArray){ jint* nativeDirectArray; jboolean isCopy; jint result = 1; jsize length = (*env)->GetArrayLength(env,javaArray); nativeDirectArray = (*env)->GetIntArrayElements(env,javaArray,&isCopy); int i = 0; for(i=0;i<length;i++){ result *= nativeDirectArray[i]; } (*env)->ReleaseIntArrayElements(env,javaArray,nativeDirectArray,0); return result; }
好了,关于数组操作就说这么多,有问题欢迎留言讨论。
相关文章推荐
- nginx主配置文件 在那找怎么打开
- @+id/android:list"的写法
- json解析中的坑+解析方法
- 深入理解HTTP Session
- Stanford机器学习---第四讲. 神经网络的表示 Neural Networks representation
- python 迭代、Iterable(可迭代)对象的判断和内置函数enumerate的使用
- 乘积最大子序列
- Drillbench Cemcalc v3.9 1CD(动态固井设计分析软件)/Drillbench Suite v6.1 1CD(钻井作业设计及规划软件)
- Linux文件系统上的特殊权限(SUID、SGID、Sticky)的知识点
- django 1.8 官方文档翻译: 3-5-2 使用Django输出PDF
- 21.备忘录模式
- Stanford机器学习---第三讲. 逻辑回归和过拟合问题的解决 logistic Regression & Regularization
- bash环境变量
- 读透一本书(转)
- Android实战简易教程-第五十三枪(通过实现OnScrollListener接口实现上拉加载更多功能)
- Flex与服务器交互之四(使用RemoteObject +BlazeDS+TomCat同Java交互及开发环境配置)
- 1055. The World's Richest (25)
- [置顶] Caffe学习笔记
- 算法导论——矩阵链乘法
- 前向型神经网络之BPNN(附源码)