罗湖商城网站建设哪家好,wordpress页尾,2022年近期重大新闻事件,wordpress 社交网站目录
0 前言
1 准备工作介绍
2 一维数组
2.1 return形式
2.2 参数形式
3 二维数组
3.1 return形式
3.2 参数形式
4 三维数组
4.1 return形式
4.2 参数形式
5 测试代码
6 结果说明 0 前言 就如之前我写过的一篇文章【JNI内形参从C代码中获取返回值并返回到Java层使…目录
0 前言
1 准备工作介绍
2 一维数组
2.1 return形式
2.2 参数形式
3 二维数组
3.1 return形式
3.2 参数形式
4 三维数组
4.1 return形式
4.2 参数形式
5 测试代码
6 结果说明 0 前言 就如之前我写过的一篇文章【JNI内形参从C代码中获取返回值并返回到Java层使用】中所描述的一样JNI编程往往需要考虑的就是如何将C/C中计算分析得到的数据传递至Java层。传递的方式就有两种①直接通过函数return出来②再就是通过形参获取得到。在以上文章内介绍了int值得传递情况这篇文章则具体讲述数组得传递方式和操作包括一维数组、二维数组以及三维数组数组使用到三维基本满足了绝大部分的使用需求了。 之所以写这篇文章也是因为检索了很久对于数组在JNI内传递数据方式只看到第一种通过return方式传递的。为此就将自己工作整理出来实现数组通过形参的方式传递数据给java层。
1 准备工作介绍 在写测试案例之前需要有系列的准备工作由于这不是重点该部分我简单介绍一下。首先需要创建java工程然后编写java文件生成JNI头文件最后编译成动态库。这里面具体可以参考【IntelliJ IDEA平台下JNI编程一—HelloWorld篇_idea jni_走召大爷的博客-CSDN博客】 本次编写环境Ubuntu18.04 、gcc7.5.0、生成.so动态库、IDEA平台。以下分别介绍在jni层不同维度数组不同形式传递数据的代码写法具体介绍可以看代码内部注释。
2 一维数组
2.1 return形式
//一维数组 return形式向JAVA传递数据
JNIEXPORT jdoubleArray Java_com_test_java_JNItest_test0(JNIEnv *env, jobject)
{int n 3; //构造/模拟一个数组double test[3] {0.0,1.0,2.0};//定义一维数组数组元素个数为n3jdoubleArray one env-NewDoubleArray(n);env-SetDoubleArrayRegion(one,0,n,test); return one;}
2.2 参数形式
//一维数组 形参向JAVA传递数据
JNIEXPORT jint Java_com_test_java_JNItest_test3
(JNIEnv *env, jobject,jdoubleArray result)
{int n 3;//构造/模拟一个数组double test[3] {0.0,1.0,2.0};env-SetDoubleArrayRegion(result,0,n,test); return 0;
}
3 二维数组
3.1 return形式
//二维数组 return形式向JAVA传递数据
JNIEXPORT jobjectArray Java_com_test_java_JNItest_test1(JNIEnv *env, jobject)
{//构造二维数组double test[2][3] {{1.0,2.0,3.0},{3.0,3.0,6.0}};//一维数组 类型定义jclass ArrCls1 env-FindClass([D); //创建一个有polygonpointNum个元素每个元素的值是NULL的一维数组的数组 jobjectArray second env-NewObjectArray(2, ArrCls1, NULL); //等同二维数组//对于二维数组其内容是每一个一维数组那么就循环定义一维数组直接存入结果里面 //对于测试的二维数组其为2x3固定的不然通过下面循环可以获取变长的数组内容for(int i 0;i 2;i){ int num 3;//定义一维数组数组元素个数为num3jdoubleArray darr env-NewDoubleArray(num);//将test的内容赋值给darrenv-SetDoubleArrayRegion(darr, 0, num, test[i]);//然后再将darr一维数组内容直接按顺序赋值给second二维数组env-SetObjectArrayElement(second, i, darr); //删除临时元素darr数组 env-DeleteLocalRef(darr); } return second;}
3.2 参数形式
//二维数组 形参向JAVA传递数据
JNIEXPORT jint Java_com_test_java_JNItest_test4(JNIEnv *env, jobject, jobjectArray result)
{//构造二维数组double test[2][3] {{1.0,2.0,3.0},{3.0,3.0,6.0}};//对于二维数组其内容是每一个一维数组那么就循环定义一维数组直接存入结果里面 //对于测试的二维数组其为2x3固定的不然通过下面循环可以获取变长的数组内容for(int i 0;i 2;i){ int num 3;//定义一维数组数组元素个数为num3jdoubleArray darr env-NewDoubleArray(num);//将test的内容赋值给darrenv-SetDoubleArrayRegion(darr, 0, num, test[i]);//然后再将darr一维数组内容直接按顺序赋值给二维结果数组如此就将c/c内部的数组内容通过result传递到java层了env-SetObjectArrayElement(result, i, darr); //删除临时元素darr数组 env-DeleteLocalRef(darr); } return 0;}
4 三维数组
4.1 return形式
//三维数组 return形式向JAVA传递数据
JNIEXPORT jobjectArray Java_com_test_java_JNItest_test2(JNIEnv *env, jobject)
{//构造一个三维数组示例为两个多边形每个多边形3个顶点每个顶点由xy组成double test[2][3][2] {{{1.0,2.0},{3.0,5.0},{2.0,4.0}},{{1.0,2.0},{3.0,5.0},{2.0,4.0}}};int polygonNum 2;//二维数组类型定义jclass ArrCls2 env-FindClass([[D); //实例化三维数组对象第一个参数数据的大小第二个参数用来实例化用的类是一个二维数组也就是数组里的每个元素都是一个二维数组 jobjectArray three env-NewObjectArray(polygonNum, ArrCls2, NULL); //这样three就是一个三维数组。for(int i 0;i polygonNum;i) { int polygonpointNum 3;//一维数组 类型定义jclass ArrCls1 env-FindClass([D); //创建一个有polygonpointNum个元素每个元素的值是NULL的一维数组的数组 jobjectArray second env-NewObjectArray(polygonpointNum, ArrCls1, NULL); //等同二维数组for (int j 0; j polygonpointNum; j) { jdouble tmp[2]; //构造每一个一维存储单元/* make sure it is large enough! */tmp[0] test[i][j][0]; tmp[1] test[i][j][1]; //也可以不构造和赋值后面one的赋值可以env-SetDoubleArrayRegion(one, 0, 2, test[i][j]);也可以的 //定义有两个元素的一维数组jdoubleArray one env-NewDoubleArray(2); //把tmp里数据从0开始传递2个到one里 env-SetDoubleArrayRegion(one, 0, 2, tmp); //给二维数组second的第j个元素设置值 env-SetObjectArrayElement(second, j, one); //注意理解内容填充数组初始化//删除临时元素one数组 env-DeleteLocalRef(one); } //给三维数组里的第i个元素设置值值是一个有一个元素组成的二维数据env-SetObjectArrayElement(three, i, second); //删除临时元素二维数组 env-DeleteLocalRef(second); } return three;
}
4.2 参数形式
//三维数组 形参向JAVA传递数据
JNIEXPORT jint Java_com_test_java_JNItest_test5(JNIEnv *env, jobject, jobjectArray result)
{//构造一个三维数组示例为两个多边形每个多边形3个顶点每个顶点由xy组成double test[2][3][2] {{{1.0,2.0},{3.0,5.0},{2.0,4.0}},{{1.0,2.0},{3.0,5.0},{2.0,4.0}}};int polygonNum 2;for(int i 0;i polygonNum;i) { int polygonpointNum 3;//一维数组 类型jclass arrClass env-FindClass([D); //创建一个有polygonpointNum个元素每个元素的值是NULL的一维数组的数组 jobjectArray second env-NewObjectArray(polygonpointNum, arrClass, NULL); //等同二维数组//给一维数据填充值 for (int j 0; j polygonpointNum; j) { jdouble tmp[2]; //构造每一个一维存储单元tmp[0] test[i][j][0]; tmp[1] test[i][j][1]; //也可以不构造和赋值后面one的赋值可以env-SetDoubleArrayRegion(one, 0, 2, test[i][j]);也可以的//创建一个有2个元素的一维数组jdoubleArray one env-NewDoubleArray(2); //把tmp里数据从0开始传递2个到one里 env-SetDoubleArrayRegion(one, 0, 2, tmp); //给二维数组second的第j个元素设置值 env-SetObjectArrayElement(second, j, one); //注意理解内容填充数组初始化//删除临时元素one数组 env-DeleteLocalRef(one); } //给需要传出的三维数组里的每个元素设置值值是一个有一个元素组成的二维数据env-SetObjectArrayElement(result, i, second); //删除临时元素二维数组 env-DeleteLocalRef(second); } return 0;}
5 测试代码 在java内的测试代码如下
package com.test.java;/*** author yh* version 1.0* date 23-3-6 下午8:58*/
public class JNItest {static {System.load(/root/workspace-yh/javaProjectTest/jni/libjnitest.so);}public native double[] test0();public native double[][] test1();public native double[][][] test2();public native int test3(double[] result);public native int test4(double[][] result);public native int test5(double[][][] result);public void printOneArray(double[] t){int n t.length;for(int i 0;i n;i){System.out.println(t[i]);}}public void printSecondArray(double[][] t){int n t.length;for(int i 0;i n;i){int m t[i].length;String temp ;for(int j 0;j m;j){temp t[i][j],;}System.out.println(temp);}}public void printThreeArray(double[][][] t){int n t.length;for(int i 0;i n;i){int m t[i].length;for(int j 0;j m;j){String temp ;int k t[i][j].length;for(int l 0;l k;l){temp t[i][j][l],;}System.out.println(temp);}}}public static void main(String[] args){JNItest JNI new JNItest();double[] a3 new double[3];double[][] a4 new double[2][2];double[][][] a5 new double[2][3][2];System.out.println(-------------------test0-----------------);double[] a0 JNI.test0();JNI.printOneArray(a0);System.out.println(-------------------test3-----------------);int rnt3 JNI.test3(a3);JNI.printOneArray(a3);System.out.println(-------------------test1-----------------);double[][]a1 JNI.test1();JNI.printSecondArray(a1);System.out.println(-------------------test4-----------------);int rnt4 JNI.test4(a4);JNI.printSecondArray(a4);System.out.println(-------------------test2-----------------);double[][][]a2 JNI.test2();JNI.printThreeArray(a2);System.out.println(-------------------test5-----------------);int rnt5 JNI.test5(a5);JNI.printThreeArray(a5);} }6 结果说明 直接执行main函数控制台打印信息 根据结果可以看到两种方式均把c/c层数据传递到了java层了。那么后面根据工程需要想怎么传递数据就怎么传递数据想怎么使用接口就怎么设计接口了。
参考文章
JNI 返回二维、三维char、float、int、long型数组到java层_谢文浩博客-CSDN博客_jni 返回二维数组
Android Studio开发之JNI层开发 --- jni层返回二维数组对象_Jimmy-CSDN博客_jni 返回二维数组
android jni jobjectArray存储输出不同类型的数据_阿文的博客-CSDN博客_jni jobjectarray