一.前言

  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. SQL Sever 基础语法(增)

    SQL Sever  插入(Insert)基础语法详解 在SQL中,向表中插入数据是最基础的,任何对数据处理的基础就是数据库有数据,对于SQL而言,向表中插入数据有多种方法,本文列举3种: (一) 标 ...

  2. List去除重复数据的五种方式

    来自:CSDN,作者:多纤果冻 链接:https://blog.csdn.net/qq_37939251/article/details/90713643 以下介绍五种-不同的方法去除 Java 中A ...

  3. 音视频开发进阶——YUV与RGB的采样与存储格式

    在上一篇文章中,我们带大家了解了视频.图像.像素和色彩之间的关系,还初步认识了两种常用的色彩空间,分别是大家比较熟悉的 RGB,以及更受视频领域青睐的 YUV.今天,我们将继续深入学习 RGB.YUV ...

  4. 帮老娘导入SF信息

    转自自己的QQ空间 2023/1/3 老娘公司要统计Excel 简单说就是把顺丰上面寄的85个快递填到表里去 再把没有寄的从那两张表加起来130多个人里面揪出来单独填表 有些企业的Excel就是个灾难 ...

  5. 【ElasticSearch】大数据量情况下的前缀、中缀实时搜索方案

    简述 业务开发中经常会遇到这样一种情况,用户在搜索框输入时要实时展示搜索相关的结果.要实现这个场景常用的方案有Completion Suggester.search_as_you_type.那么这两种 ...

  6. pip安装pyinstaller失败的解决方法

    错误情况: 从下面错误来看,是安装build的依赖失败 解决方法: 下载setup.py文件来安装 1.先下载 pyinstaller的安装文件,下载地址:http://www.pyinstaller ...

  7. VUE3、ElementPlus 重构若依vue2 表单构建功能

    Vue3 + ElementPlus + Vite 重构 若依Vue2 表单构建功能 若依官方的Vue3 版本发布已经有段时间了,就是这个表单构建功能一直没有安排计划去适配到Vue3! 前段时间公司需 ...

  8. 你真的知道吗?catch、finally和return哪个先执行

    我的一位朋友前阵子遇到一个问题,问题的核心就是try--catch--finally中catch和finally代码块到底哪个先执.这个问题看起来很简单,当然是"catch先执行.final ...

  9. NAT与NAT实验

    1.NAT与NAT实验 NAT(网络地址翻译) 一个数据包目的ip或者源ip为私网地址, 运营商的设备无法转发数据. 实际场景问题 如下图 201.0.0.1 公网地址?   买的 运营商给你的​19 ...

  10. 05 地址解析协议ARP

    地址解析协议(ARP) ARP(Address Resolution Protocol)地址解析协议: 根据已知的IP地址解析获得其对应的MAC地址 ARP工作流程 1.HOST1 ARP缓存 HOS ...