NDK开发之数组操作
JNI把Java数组当作引用类型来处理,JNI提供了必要的函数来访问和处理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;
}
好了,关于数组操作就说这么多,有问题欢迎留言讨论。
版权声明:本文为博主原创文章,未经博主允许不得转载。若有错误地方,还望批评指正,不胜感激。
NDK开发之数组操作的更多相关文章
- NDK开发之字符串操作
在JNI中,Java字符串被当作一个引用来处理.这些引用类型并不像原生C字符串一样可以直接使用,JNI提供了Java字符串与C字符串之间转换的必要函数,因为Java字符串对象是不可变的(如果对这里有异 ...
- Android NDK开发篇(五):Java与原生代码通信(数据操作)
尽管说使用NDK能够提高Android程序的运行效率,可是调用起来还是略微有点麻烦.NDK能够直接使用Java的原生数据类型,而引用类型,由于Java的引用类型的实如今NDK被屏蔽了,所以在NDK使用 ...
- Android NDK开发 JNI操作java构造方法,普通方法,静态方法(七)
Android NDK开发 JNI操作java普通.静态.构造方法 1.Jni实例化一个Java类的实例jobject 1.通过FindClas( ),获取Java类的的jclass 2.通过GetM ...
- Android NDK开发篇:Java与原生代码通信(数据操作)
虽然说使用NDK可以提高Android程序的执行效率,但是调用起来还是稍微有点麻烦.NDK可以直接使用Java的原生数据类型,而引用类型,因为Java的引用类型的实现在NDK被屏蔽了,所以在NDK使用 ...
- NDK开发—基础知识实战Demo
简介 前面写了几篇NDK相关的文章: NDK开发-简介&环境搭建(Eclipse,Android Studio) NDK开发-Android Studio+gradle-experimenta ...
- NDK开发-零散知识点整理
JavaVM 标准Java平台下,每一个Process可以产生很多JavaVM对象,但在Android平台上,每一个Process只能产生一个Dalvik VM对象,也就是说在Android进程中是通 ...
- Android NDK开发入门实例
AndroidNDK是能使Android应用开发者把从c/c++编译而来的本地代码嵌入到应用包中的一系列工具的组合. 注意: AndroidNDK只能用于Android1.5及以上版本中. I. An ...
- NDK开发总结
NDK开发差不多结束了, 估计后面也不会再碰了诶, 想着还是写个总结什么的,以后捡起来也方便哈.既然是总结,我这里就不会谈具体的细节,只会记录下我觉得重要的东西, 所以这篇随笔不是为萌新学习新知识准备 ...
- Android NDK 开发(四)java传递数据到C【转】
转载请注明出处:http://blog.csdn.net/allen315410/article/details/41845701 前面几篇文章介绍了Android NDK开发的简单概念.常见错误及处 ...
随机推荐
- Logstash同步Oracle数据到ElasticSearch
最近在项目上应用到了ElasticSearch和Logstash,在此主要记录了Logstash-input-jdbc同步Oracle数据库到ElasticSearch的主要步骤,本文是对环境进行简单 ...
- iOS各种系统通知Name
当了一次搬运工,原地址:http://blog.csdn.net/db905517804/article/details/50569949 用法: - (void) viewWillAppear:(B ...
- NODE.JS玩玩
按一个网页的来,最好最后能到EXPRESS.JS. http://www.nodebeginner.org/index-zh-cn.html 这样就能对比DJANGO,看看两者的WEB框架,加深认识. ...
- 关于后缀数组的倍增算法和height数组
自己看着大牛的论文学了一下后缀数组,看了好久好久,想了好久好久才懂了一点点皮毛TAT 然后就去刷传说中的后缀数组神题,poj3693是进化版的,需要那个相同情况下字典序最小,搞这个搞了超久的说. 先简 ...
- VC自动与Internet时间服务器同步更新
在VCKBASE.CSDN里挖了许久的坟,才找到一些有点用的资料,最后自己整理出这样的个函数,方面VC实现时间同步,多的不说,自己看源码,根据自己的需要可以适当修改源码: #include <W ...
- 【Xamarin开发 Android 系列 13】 应用打包部署
原文:[Xamarin开发 Android 系列 13] 应用打包部署 开始倒叙咯................ 先更新大宝部署吧,这个章节比较的Easy,童鞋们不用费脑筋.点解?从界面上填写几个参 ...
- bzoj1232
由题意知,最后要保留的边肯定都要被走过 来回一条边所花费的时间=2*边长+安慰边两端的牛所要花的时间和 总时间就等于所保留边来回的时间和+根节点时间: 不难想到做一下最小生成树即可 贪心可知,根一定选 ...
- 你所不知道的C++
C++与C的不同 C++从诞生之初就号称和C是兼容的,正是这种兼容,使C++得以迅猛发展,然而也正是这种兼容,让C++背上了沉重的历史包袱.且不论其利弊,让我们来看看C++在兼容C的那部分中,与C语言 ...
- 【转】 Android SDK无法更新解决方法---不错
原文网址:http://blog.csdn.net/shi_weihappy/article/details/41847997 自己的修改: 203.208.39.238 dl.google.com7 ...
- Eclipse超级完美汉化教程
转自:http://jingyan.baidu.com/article/e75057f28401a8ebc91a899e.html 是中国人都喜欢汉化的东西,除非你想挑战英文,抑或你就是英语高手.百度 ...