JNI编程之java层和native层的数组数据的交互
一.前言
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层的数组数据的交互的更多相关文章
- Android Java层,Native层,Lib层打印Log简介【转】
本文转载自:https://blog.csdn.net/AndroidMage/article/details/52225068 说明: 这里我根据个人工作情况说明在各个层打印log.如有问题欢迎拍砖 ...
- framework层和native层实现联网控制(iptable方式)
最近工作中,需要开发一个功能----联网控制,这个功能其实用过root的安卓机应该都知道,禁止某个应用连接移动网络或者wifi. root后,通过su去执行iptable的命令就可以根据uid去控制应 ...
- 并发编程之 Java 内存模型 + volatile 关键字 + Happen-Before 规则
前言 楼主这个标题其实有一种作死的味道,为什么呢,这三个东西其实可以分开为三篇文章来写,但是,楼主认为这三个东西又都是高度相关的,应当在一个知识点中.在一次学习中去理解这些东西.才能更好的理解 Jav ...
- 并发编程之 Java 三把锁
前言 今天我们继续学习并发.在之前我们学习了 JMM 的知识,知道了在并发编程中,为了保证线程的安全性,需要保证线程的原子性,可见性,有序性.其中,synchronized 高频出现,因为他既保证了原 ...
- 并发编程之Java内存模型
在介绍Java内存模型之前,先来了解一下为什么要有内存模型,以及内存模型是什么.然后我们基于对内存模型的了解,学习Java内存模型以及并发编程的三大特性. 为什么要有内存模型 在计算机中,所有的运算操 ...
- 并发编程之Java锁
一.重入锁 锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized(重量级) 和 ReentrantLock(轻量级)等等 ) .这些已经写好提供的锁为我们开发提 ...
- Java并发编程之java.util.concurrent包下常见类的使用
一,Condition 一个场景,两个线程数数,同时启动两个线程,线程A数1.2.3,然后线程B数4.5.6,最后线程A数7.8.9,程序结束,这涉及到线程之间的通信. public class Co ...
- spark 独立应用编程之 Java 编程
文章更新于:2020-04-03 按照惯例,文件附上链接放在文首. 文件名:apache-maven-3.6.3-bin.tar.gz 文件大小:9.1 MB 下载链接:https://www.lan ...
- 白话说编程之java线程
线程和进程: 在说多线程之前,我们先来研究一下线程,说到线程,我们又不得不说到进程,因为很多初学者会把线程和进程分不清,搞混淆. 进程: 是操作系统系统运行的最小单元.怎么理解这句话,可以这样去对比, ...
- 并发编程之java内存模型(Java Memory Model ,JMM)
一.图例 0.两个概念 Heap(堆):运行时的数据区,由垃圾回收负责,运行时分配内存(所以慢),对象存放在堆上 如果两个线程,同时调用同一个变量,怎两个线程都拥有,该对象的私有拷贝 (可以看一下,T ...
随机推荐
- 前端Vue自定义简单通用省市区选择器picker地区选择器picker 收获地址界面模版
前端Vue自定义简单通用省市区选择器picker地区选择器picker 收获地址界面模版,下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin ...
- 前端Vue组件之仿京东拼多多领取优惠券弹出框popup 可用于电商商品详情领券场景使用
随着技术的发展,开发的复杂度也越来越高,传统开发方式将一个系统做成了整块应用,经常出现的情况就是一个小小的改动或者一个小功能的增加可能会引起整体逻辑的修改,造成牵一发而动全身.通过组件化开发,可以有效 ...
- 每日一题 力扣 445 https://leetcode.cn/problems/add-two-numbers-ii/
可以直接用栈去做就行,逆序想到栈的做法 然后算完一个就直接赋值给答案数组 我用的是常见 public ListNode addTwoNumbers(ListNode l1, ListNode l2) ...
- FlutterWeb部署到服务器
目标:把flutter web项目部署到自己的服务器上,可以使用自己的服务器IP访问 前提:服务器已经安装了nginx, 这是我的flutter配置 edz@lwqdeMacBook-Pro ~ % ...
- Hexo博客Next主题valine评论系统邮件提醒
简介 Valine:一款快速.简洁且高效的无后端评论系统. Valine-Admin Github 项目地址,具体教程以 最新版 为准 Valine-Admin项目地址 简介 Valine Admin ...
- Kerberos、黄金票据与白银票据
kerberos Kerberos是一个网络认证协议,用于验证用户和服务之间的身份,解决分布式计算环境中的身份验证问题.它使用加密技术来提供安全的身份验证,并防止网络中的身份欺骗攻击.Kerberos ...
- Semantic Kernel Java SDK,为Java应用程序提供AI功能集成
美国时间 2023 年 7 月 19 日,Semantic Kernel 团队在其官方博客[1]上宣布发布 Java 版Semantic Kernel. Samantic Kernel系列的源代码可在 ...
- FreeBSD 内核模块和硬盘相关
查看已加载的内核模块 使用命令:kldstat 加载驱动: kldload xx 查看识别到的硬盘 使用命令:dmesg | grep sector freeBSD 查看硬件信息 使用命令:dmesg ...
- vim玩法 .vimrc配置映射指令nnoremap、inoremap
编辑 vimrc 文件, vi ~/.vimrc vim中的映射指令,用于将一个按键绑定到某一个操作上. map: 执行映射指令,执行时会进行递归替换,可能会出现"按键循环"的情况 ...
- 2023-08-02:给定一棵树,一共有n个点, 每个点上没有值,请把1~n这些数字,不重复的分配到二叉树上, 做到 : 奇数层节点的值总和 与 偶数层节点的值总和 相差不超过1。 返回奇数层节点分配
2023-08-02:给定一棵树,一共有n个点, 每个点上没有值,请把1~n这些数字,不重复的分配到二叉树上, 做到 : 奇数层节点的值总和 与 偶数层节点的值总和 相差不超过1. 返回奇数层节点分配 ...