摘要:本文主要向大家介绍了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的介绍,先祝大家对它有了一定的了解吧,了解更多内容,请关注职坐标编程语言JAVA频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号