一.前言

  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. CAN转PROFINET协议网关 JM-PN-CAN

        1 产品功能 捷米特JM-PN-CAN 是自主研发的一款 PROFINET 从站功能的通讯网关.主要功能是将各种 CAN 设备接入到 PROFINET 网络中. 捷米特JM-PN-CAN连接到 ...

  2. python学习--采集弹幕信息

    # -*- coding: utf-8 -*-"""Created on Mon Nov 4 12:00:12 2019 @author: DELL"" ...

  3. Unity的IPreprocessBuild:深入解析与实用案例

    Unity IPreprocessBuild Unity IPreprocessBuild是Unity引擎中的一个非常有用的功能,它可以让开发者在构建项目时自动执行一些操作.这个功能可以帮助开发者提高 ...

  4. HBase架构和技术原理介绍

    一.HBase数据模型(☆) 1.NameSpace 命名空间,类似于关系型数据库的 DataBase 概念,每个命名空间下有多个表.HBase有两个自带的命名空间,分别是 hbase 和 defau ...

  5. javascript中一些难以理解的专有名词 2(也不是很专有)

    作用域链 让人迷惑的例子 function foo() {console.log(v)} function foo1() { var v = "v1" foo() console. ...

  6. AI 一键去水印:教你无限量使用商业图片的技巧

    场景再现 刚开始注册账号(啥账号具体不表了,小编不喜欢的那个),想弄个闪亮,好看,有个性化的 Logo.作为一名非专美工小白人员,网上翻了很久作图工具,要么就是不好用,好用的大部分都收费.最后没办法, ...

  7. 一文了解react中定义样式(css/less/sass)的常用方法

    react中通过jsx的语法方式,将html标签和js语法联系在一起,而css的编写方式,没有明确的指定编写方式,目前就有很多不同方法,每个方式各有其优缺点,我们一起来看看常用的定义方式有哪些. 最基 ...

  8. 熟悉又陌生的package.json

    前言 随着前端的不断发展,package.json可谓是在前端项目中无处不在,它不仅在项目根目录会有,而且在 node_modules 中也存在.那么这个文件到底是干嘛的,又有什么作用?很多人对它的认 ...

  9. Vue3 路由优化,使页面初次渲染效率翻倍

    3996 条路由? addRoute函数用了大约1s才执行完毕.通过观察,发现居然有3996条路由记录. 可是项目并没有这么多的页面啊~ 重复路由 let routes: Array<Route ...

  10. Hugging Face 的文本生成和大语言模型的开源生态

    [更新于 2023 年 7 月 23 日: 添加 Llama 2.] 文本生成和对话技术已经出现多年了.早期的挑战在于通过设置参数和分辨偏差,同时控制好文本忠实性和多样性.更忠实的输出一般更缺少创造性 ...