JAVA语言JNI的使用详解第五篇:C C++中操作Java中的数组
Vivian 2018-06-26 来源 : 阅读 559 评论 0

摘要:本文主要向大家介绍了JAVA语言JNI的使用的C C++中操作Java中的数组,通过具体的代码向大家展示,希望对大家学习JAVA语言有所帮助。

本文主要向大家介绍了JAVA语言JNI的使用的C C++中操作Java中的数组,通过具体的代码向大家展示,希望对大家学习JAVA语言有所帮助。

在Java中数组分为两种:

1.基本类型数组

2.对象类型(Object[])的数组(数组中存放的是指向Java对象中的引用)

一个能通用于两种不同类型数组的函数:

GetArrayLength(jarray array);

 

首先来看一下怎么处理基本类型的数组:

(1) Get<Type>ArrayElements(<Type>Array arr , jboolean* isCopide);

这类函数可以把Java基本类型的数组转换到C/C++中的数组,有两种处理方式,一种是拷贝一份传回本地代码,另一个是把指向Java数组的指针直接传回到本地代码中,处理完本地化的数组后,通过Release<Type>ArrayElements来释放数组

 

(2) Release<Type>ArrayElements(<Type>Array arr , <Type>* array , jint mode)

用这个函数可以选择将如何处理Java跟C++的数组,是提交,还是撤销等,内存释放还是不释放等

mode可以取下面的值:

0 :对Java的数组进行更新并释放C/C++的数组

JNI_COMMIT :对Java的数组进行更新但是不释放C/C++的数组

JNI_ABORT:对Java的数组不进行更新,释放C/C++的数组

 

(3) GetPrimittiveArrayCritical(jarray arr , jboolean* isCopied);

(4) ReleasePrimitiveArrayCritical(jarray arr , void* array , jint mode);

也是JDK1.2出来的,为了增加直接传回指向Java数组的指针而加入的函数,同样的也会有同GetStringCritical的死锁的问题

 

(5) Get<Type>ArrayRegion(<Type>Array arr , jsize start , jsize len , <Type>* buffer);

在C/C++预先开辟一段内存,然后把Java基本类型的数组拷贝到这段内存中,这个方法和之前拷贝字符串的GetStringRegion方法的原理是类似的

 

(6) Set<Type>ArrayRegion(<Type>Array arr , jsize start , jsize len , const <Type>* buffer);

把Java基本类型的数组中的指定范围的元素用C/C++的数组中的元素来赋值

 

(7) <Type>Array New<Type>Array(jsize sz)

指定一个长度然后返回相应的Java基本类型的数组

 

在来看一下怎么处理对象型数组

JNI没有提供直接把Java的对象类型数组(Object[])直接转到C++中的Object[]数组的函数,而是直接通过Get/SetObjectArrayElement这样的函数来对Java的Object[]数组进行操作由于去的对象数组没有进行拷贝,所以不需要释放任何资源

NewObjectArray可以通过指定长度跟初始值来创建某个类的数组

 

下面来看一下例子:操作两种类型的数组

Java中的代码:

[java] view plaincopy
1. package com.jni.demo;  
2.   
3. public class JNIDemo {  
4.     //定义一个int型数组  
5.     int[] arrays = {4,3,12,56,1,23,45,67};  
6.     //定义Father对象数组  
7.     Father[] objArrays = {new Father(),new Father(),new Father()};   
8.     //定义一个本地方法  
9.     public native void callCppFunction();  
10.     public static void main(String[] args)throws Exception{  
11.         //调用动态链接库  
12.         System.loadLibrary("JNIDemo");  
13.         JNIDemo jniDemo = new JNIDemo();  
14.         jniDemo.callCppFunction();  
15.           
16.     }  
17. }  
18. </span>  
C++中的代码:[cpp] view plaincopy
1. #include<iostream>  
2. #include"com_jni_demo_JNIDemo.h"  
3. #include<algorithm>  
4. using namespace std;  
5.   
6. JNIEXPORT void JNICALL Java_com_jni_demo_JNIDemo_callCppFunction (JNIEnv * env, jobject obj)  
7. {  
8.     //获取Java中数组属性arrays的id  
9.     jfieldID fid_arrays = env->GetFieldID(env->GetObjectClass(obj),"arrays","[I");  
10.     //获取Java中数组属性arrays的对象  
11.     jintArray jint_arr = (jintArray)env->GetObjectField(obj,fid_arrays);  
12.     //获取arrays对象的指针  
13.     jint* int_arr = env->GetIntArrayElements(jint_arr,NULL);  
14.     //获取数组的长度  
15.     jsize len = env->GetArrayLength(jint_arr);  
16.     //打印数组中的值  
17.     cout<<"数组的值为:";  
18.     for(int s =0;s<len;s++){  
19.         cout<<int_arr[s]<<',';  
20.     }  
21.     cout<<endl;  
22.   
23.     //新建一个jintArray对象  
24.     jintArray jint_arr_temp = env->NewIntArray(len);  
25.     //获取jint_arr_temp对象的指针  
26.     jint* int_arr_temp = env->GetIntArrayElements(jint_arr_temp,NULL);  
27.     //计数  
28.     jint count = 0;  
29.     //偶数位存入到int_arr_temp内存中  
30.     for(jsize j=0;j<len;j++){  
31.         if(j%2==0){  
32.             int_arr_temp[count++] = int_arr[j];       
33.         }  
34.     }  
35.     //打印int_arr_temp内存中的数组  
36.     cout<<"数组中位置是偶数的值为:";  
37.     for(jsize k=0;k<count;k++){  
38.         cout<<int_arr_temp[k]<<',';  
39.     }  
40.     cout<<endl;  
41.   
42.     //将数组中一段(0-2)数据拷贝到内存中,并且打印出来  
43.     jint* buffer = new jint[len];  
44.     //获取数组中从0开始长度为3的一段数据值  
45.     env->GetIntArrayRegion(jint_arr,0,3,buffer);  
46.     cout<<"打印数组中0-3一段值:";  
47.     for(int l=0;l<3;l++){  
48.         cout<<buffer[l]<<',';  
49.     }  
50.     cout<<endl;  
51.   
52.     //将数组中的一段(3-7)设置成一定的值,并且打印出来  
53.     jint* buffers = new jint[4];  
54.     for(int n=0;n<4;n++){  
55.         buffers[n] = n+1;  
56.     }  
57.     //将buffers这个数组中值设置到数组从3开始长度是4的值中  
58.     env->SetIntArrayRegion(jint_arr,3,4,buffers);  
59.     //从新获取数组指针  
60.     int_arr = env->GetIntArrayElements(jint_arr,NULL);  
61.     cout<<"数组中3-7这段的值变成了:";  
62.     for(int m=0;m<len;m++){  
63.         cout<<int_arr[m]<<',';  
64.     }  
65.     cout<<endl;  
66.   
67.     //调用C++标准库中的排序方法sort(...),传递一个数组的开始指针和结束指针  
68.     std::sort(int_arr,int_arr+len);  
69.     //迭代打印数组中的元素  
70.     cout<<"数组排序后的结果:";  
71.     for(jsize i=0;i<len;i++){  
72.         cout<<int_arr[i]<<',';  
73.     }  
74.     cout<<endl;  
75.     //释放数组指针  
76.     env->ReleaseIntArrayElements(jint_arr,int_arr,JNI_ABORT);  
77.   
78.     //获取Java中对象Father数组属性的id  
79.     jfieldID fid_obj_arrays = env->GetFieldID(env->GetObjectClass(obj),"objArrays","[Lcom/jni/demo/Father;");  
80.     //获取Java中对象数组Father属性objArrays的对象  
81.     jobjectArray jobj_arr = (jobjectArray)env->GetObjectField(obj,fid_obj_arrays);  
82.     //从对象数组中获取索引值为1的对象Father  
83.     jobject jobj = env->GetObjectArrayElement(jobj_arr,1);  
84.     //获取Father对象的class对象    
85.     jclass clazz_father = env->GetObjectClass(jobj);    
86.     //获取Father对象中的function方法的id    
87.     jmethodID id_father_function = env->GetMethodID(clazz_father,"function","()V");    
88.     //调用Father对象中的function方法  
89.     env->CallVoidMethod(jobj,id_father_function);     
90.       
91.     //在本地创建一个大小为10的对象数组,对象的初始化都是jobj,也就是方法的第三个参数  
92.     jobjectArray jobj_arr_temp = env->NewObjectArray(10,env->GetObjectClass(jobj),jobj);  
93.     //获取本地对象数组中第4个对象  
94.     jobject jobj_temp = env->GetObjectArrayElement(jobj_arr_temp,3);  
95.     //调用Father对象中的function方法  
96.     env->CallVoidMethod(jobj_temp,id_father_function);    
97.   
98. }  
99. </span>


在Eclipse编译运行结果如下:

 JAVA语言JNI的使用详解第五篇:C C++中操作Java中的数组

以上就是职坐标整理发布关于JAVA的介绍,先祝大家对它有了一定的了解吧,了解更多内容,请关注职坐标编程语言JAVA频道!

本文由 @Vivian 发布于职坐标。未经许可,禁止转载。
喜欢 | 2 不喜欢 | 0
看完这篇文章有何感觉?已经有2人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程