在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中的代码:
- packagecom.jni.demo;
-
- publicclassJNIDemo{
-
- int[]arrays={4,3,12,56,1,23,45,67};
-
- Father[]objArrays={newFather(),newFather(),newFather()};
-
- publicnativevoidcallCppFunction();
- publicstaticvoidmain(String[]args)throwsException{
-
- System.loadLibrary("JNIDemo");
- JNIDemojniDemo=newJNIDemo();
- jniDemo.callCppFunction();
-
- }
- }
- </span>
C++中的代码:
- #include<iostream>
- #include"com_jni_demo_JNIDemo.h"
- #include<algorithm>
- usingnamespacestd;
-
- JNIEXPORTvoidJNICALLJava_com_jni_demo_JNIDemo_callCppFunction(JNIEnv*env,jobjectobj)
- {
-
- jfieldIDfid_arrays=env->GetFieldID(env->GetObjectClass(obj),"arrays","[I");
-
- jintArrayjint_arr=(jintArray)env->GetObjectField(obj,fid_arrays);
-
- jint*int_arr=env->GetIntArrayElements(jint_arr,NULL);
-
- jsizelen=env->GetArrayLength(jint_arr);
-
- cout<<"数组的值为:";
- for(ints=0;s<len;s++){
- cout<<int_arr[s]<<',';
- }
- cout<<endl;
-
-
- jintArrayjint_arr_temp=env->NewIntArray(len);
-
- jint*int_arr_temp=env->GetIntArrayElements(jint_arr_temp,NULL);
-
- jintcount=0;
-
- for(jsizej=0;j<len;j++){
- if(j%2==0){
- int_arr_temp[count++]=int_arr[j];
- }
- }
-
- cout<<"数组中位置是偶数的值为:";
- for(jsizek=0;k<count;k++){
- cout<<int_arr_temp[k]<<',';
- }
- cout<<endl;
-
-
- jint*buffer=newjint[len];
-
- env->GetIntArrayRegion(jint_arr,0,3,buffer);
- cout<<"打印数组中0-3一段值:";
- for(intl=0;l<3;l++){
- cout<<buffer[l]<<',';
- }
- cout<<endl;
-
-
- jint*buffers=newjint[4];
- for(intn=0;n<4;n++){
- buffers[n]=n+1;
- }
-
- env->SetIntArrayRegion(jint_arr,3,4,buffers);
-
- int_arr=env->GetIntArrayElements(jint_arr,NULL);
- cout<<"数组中3-7这段的值变成了:";
- for(intm=0;m<len;m++){
- cout<<int_arr[m]<<',';
- }
- cout<<endl;
-
-
- std::sort(int_arr,int_arr+len);
-
- cout<<"数组排序后的结果:";
- for(jsizei=0;i<len;i++){
- cout<<int_arr[i]<<',';
- }
- cout<<endl;
-
- env->ReleaseIntArrayElements(jint_arr,int_arr,JNI_ABORT);
-
-
- jfieldIDfid_obj_arrays=env->GetFieldID(env->GetObjectClass(obj),"objArrays","[Lcom/jni/demo/Father;");
-
- jobjectArrayjobj_arr=(jobjectArray)env->GetObjectField(obj,fid_obj_arrays);
-
- jobjectjobj=env->GetObjectArrayElement(jobj_arr,1);
-
- jclassclazz_father=env->GetObjectClass(jobj);
-
- jmethodIDid_father_function=env->GetMethodID(clazz_father,"function","()V");
-
- env->CallVoidMethod(jobj,id_father_function);
-
-
- jobjectArrayjobj_arr_temp=env->NewObjectArray(10,env->GetObjectClass(jobj),jobj);
-
- jobjectjobj_temp=env->GetObjectArrayElement(jobj_arr_temp,3);
-
- env->CallVoidMethod(jobj_temp,id_father_function);
-
- }
- </span>
在Eclipse编译运行结果如下:
不要以为这就结束了,后面还有很多内容呀!