一.前言

  JNI中的数组类型分为基本类型数组和引用类型数组,他们的处理方式是不一样的。基本类型数组中的元素都是jni基本数据类型,可以直接访问;但是引用类型的数组中的元素是一个类的实例,不能直接访问,需要使用jni中的函数进行访问。

二.基本类型数组的交互

  1.java层声明的native函数如下:

public native double[] arrayAsArgs(int[] a);//求数组的和以及平均数,并以数组的形式返回

  2.native层代码:

jdoubleArray native_arrayAsArgs(JNIEnv *env,jobject thiz,jintArray array){
jint *a=env->GetIntArrayElements(array, nullptr);//获取java层数组的值,并赋给jint*指针变量
jsize length=env->GetArrayLength(array);//获取java层数组的长度
jint sum=0;
jdouble avg=0.0;
for(int i=0;i<length;i++){
sum+=*(a+i);//访问每一个数组元素并累加
}
avg=(jdouble)sum/length;
env->ReleaseIntArrayElements(array,a,0);//和GetIntArrayElements()是一对的,使用完之后就要释放内存,防止内存泄漏
jdouble result[]={(jdouble)sum,avg};
jdoubleArray result1=env->NewDoubleArray(2);//开辟内存空间,相当于new double[2]
env->SetDoubleArrayRegion(result1,0,2,result);//给数组赋值
return result1;
}

三.引用类型数组的交互

  1.java层声明的native函数如下:

public native String[] quoteArrayAsArgs(String[] s);//从java中传入引用数组到native层,并返回相同的引用数组到java层

  2.native层代码:

jobjectArray native_quoteArrayAsArgs(JNIEnv *env,jobject thiz,jobjectArray s){
jclass clazz=env->FindClass("java/lang/String");
jsize length=env->GetArrayLength(s);
jstring str;
jstring str1[length];
for(int i=0;i<length;i++){//获取java层引用数组中每个元素的值,并存储在str1数组中
str=(jstring)env->GetObjectArrayElement(s,i);
str1[i]=str;
}
jobjectArray str2;
str2=env->NewObjectArray(length,clazz, nullptr);//为引用数组开辟内存,相当于new String[length]
for(int i=0;i<length;i++){
env->SetObjectArrayElement(str2,i,str1[i]);
}
return str2;
}

四.二维数组的交互

  二维数组可以看作特殊的一维数组,数组中的每个元素的类型是一维数组,也就是说每个元素是一个引用类型的数据,这样理解之后,代码就好写了。

  1.java层声明的native函数如下:

public native char[][] twoDimenArrayAsArgs(char[][] c);//原封不动的返回c

  2.native层代码:

jobjectArray native_towDimenArrayAsArgs(JNIEnv *env,jobject thiz,jobjectArray c){
jsize rows=env->GetArrayLength(c);//获取行数
jcharArray cc=(jcharArray)env->GetObjectArrayElement(c,0);
jsize cols=env->GetArrayLength(cc);//获取列数
jchar result[rows][cols];
for(int i=0;i<rows;i++){
cc=(jcharArray)env->GetObjectArrayElement(c,i);
jchar *character=env->GetCharArrayElements(cc, nullptr);
for(int j=0;j<cols;j++){
result[i][j]=*(character+j);
}
env->ReleaseCharArrayElements(cc,character,0);
}
jclass clazz=env->FindClass("[C");//char[]的Class对象
jobjectArray ret=env->NewObjectArray(rows,clazz, nullptr);
for(int i=0;i<rows;i++){
jcharArray jcharArray=env->NewCharArray(cols);
env->SetCharArrayRegion(jcharArray,0,cols,result[i]);
env->SetObjectArrayElement(ret,i,jcharArray);
}
return ret;
}

  如果是其他类型的数组,将类型换成其他类型即可,代码不用变。

JNI编程之java层和native层的数组数据的交互的更多相关文章

  1. Android Java层,Native层,Lib层打印Log简介【转】

    本文转载自:https://blog.csdn.net/AndroidMage/article/details/52225068 说明: 这里我根据个人工作情况说明在各个层打印log.如有问题欢迎拍砖 ...

  2. framework层和native层实现联网控制(iptable方式)

    最近工作中,需要开发一个功能----联网控制,这个功能其实用过root的安卓机应该都知道,禁止某个应用连接移动网络或者wifi. root后,通过su去执行iptable的命令就可以根据uid去控制应 ...

  3. 并发编程之 Java 内存模型 + volatile 关键字 + Happen-Before 规则

    前言 楼主这个标题其实有一种作死的味道,为什么呢,这三个东西其实可以分开为三篇文章来写,但是,楼主认为这三个东西又都是高度相关的,应当在一个知识点中.在一次学习中去理解这些东西.才能更好的理解 Jav ...

  4. 并发编程之 Java 三把锁

    前言 今天我们继续学习并发.在之前我们学习了 JMM 的知识,知道了在并发编程中,为了保证线程的安全性,需要保证线程的原子性,可见性,有序性.其中,synchronized 高频出现,因为他既保证了原 ...

  5. 并发编程之Java内存模型

    在介绍Java内存模型之前,先来了解一下为什么要有内存模型,以及内存模型是什么.然后我们基于对内存模型的了解,学习Java内存模型以及并发编程的三大特性. 为什么要有内存模型 在计算机中,所有的运算操 ...

  6. 并发编程之Java锁

    一.重入锁 锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized(重量级) 和 ReentrantLock(轻量级)等等 ) .这些已经写好提供的锁为我们开发提 ...

  7. Java并发编程之java.util.concurrent包下常见类的使用

    一,Condition 一个场景,两个线程数数,同时启动两个线程,线程A数1.2.3,然后线程B数4.5.6,最后线程A数7.8.9,程序结束,这涉及到线程之间的通信. public class Co ...

  8. spark 独立应用编程之 Java 编程

    文章更新于:2020-04-03 按照惯例,文件附上链接放在文首. 文件名:apache-maven-3.6.3-bin.tar.gz 文件大小:9.1 MB 下载链接:https://www.lan ...

  9. 白话说编程之java线程

    线程和进程: 在说多线程之前,我们先来研究一下线程,说到线程,我们又不得不说到进程,因为很多初学者会把线程和进程分不清,搞混淆. 进程: 是操作系统系统运行的最小单元.怎么理解这句话,可以这样去对比, ...

  10. 并发编程之java内存模型(Java Memory Model ,JMM)

    一.图例 0.两个概念 Heap(堆):运行时的数据区,由垃圾回收负责,运行时分配内存(所以慢),对象存放在堆上 如果两个线程,同时调用同一个变量,怎两个线程都拥有,该对象的私有拷贝 (可以看一下,T ...

随机推荐

  1. decode php解密代码,方便好用,请收藏

    <?php //已经加密的文件内容 $a = "eval(gzinflate(base64_decode('tVRNb+IwEL3vr/AhwomU5WOPVHSF2lSg7QJK0j ...

  2. influxdb常用sql总结

    本文为博主原创,转载请注明出处: 1.登录influxdb influx -username admin -password "password" 2.查看数据库 ##查看有哪些数 ...

  3. RocketMq5.0 任意延迟时间 TimerMessageStore 源码解析

    TimerMessageStore 简略介绍 延迟队列 rmq_sys_wheel_timer 指定时间的延迟消息.会先投递到 rmq_sys_wheel_timer 队列中 然后由 TimerMes ...

  4. 基于JavaFX的扫雷游戏实现(四)——排行榜

      这期看标题已经能猜到了,主要讲的是成绩排行功能,还有对应的文件读写.那么废话不多说,让我们有请今天的主角...的设计稿:   那么主角是何方神圣呢?当然是图中的大框框--TableView.关于这 ...

  5. 我开源了团队内部基于SpringBoot Web快速开发的API脚手架stater

    我们现在使用SpringBoot 做Web 开发已经比之前SprngMvc 那一套强大很多了. 但是 用SpringBoot Web 做API 开发还是不够简洁有一些. 每次Web API常用功能都需 ...

  6. Word书签替换,加盖电子印章及转换PDF(Java实用版)

    一.前言 在项目中有需要对word进行操作的,可以看看哈,本次使用比较强大的spire组件来对word进行操作,免费版支持三页哦,对于不止三页的word文件,可以购买收费版,官网:https://ww ...

  7. pytesseract and ddddocr

    一.pytesseract 1.简介 Pytesseract是一个Python库,用于将图像中的文本转换为可编辑的字符串.它是基于Google的Tesseract OCR引擎开发的 .Tesserac ...

  8. 【go语言】1.1.1 Go 语言的历史和背景

    Go 语言,也被称为 Golang,是一种静态强类型.编译型的开源编程语言.Go 语言的出现是为了解决当下的软件开发问题,特别是大规模软件系统的开发. Go 语言的设计者包括 Robert Gries ...

  9. Linux 中设备的分类及网络设备接口路径

    设备分类 字符设备 块设备 网络设备 参考文档: 手把手教Linux驱动 网络设备位置 [root@localhost ~]# cd /sys/class/net/ [root@localhost n ...

  10. python教程 入门学习笔记 第4天 数据类型 获取数据类型 字符串拼接

    数据类型 1.能直接处理的基本数据类型有5个:整型.浮点型.字符串.布尔值.空 1)整型(int)=整数,例如0至9,-1至-9,100,-8180等,人数.年龄.页码.门牌号等 没有小数位的数字,是 ...