处理数组
数组分为两类:1.基本类型的数组 2.对象(Object[])的数组
获取数组长度
jsize GetArrayLength(jarray array) {
return functions->GetArrayLength(this,array);
}
处理基本数据类型数组
处理基本类型的数据的时候也是跟处理字符串,有很相似的函数。
Get<Type>ArrayElements(<Type>Array arr, jboolean* isCopied);这类函数可以把Java基本类型的数组转换到c/c++中的数组。有两种处理方式,一是复制一份传回本地代码,另外是把指向Java数组的指针直接传回到本地代码,处理完本地化的数组后,通过Release<Type>ArrayElements来释放数组。
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++的数组
void * GetPrimitiveArrayCritical(jarray array, jboolean *isCopy) {
return functions->GetPrimitiveArrayCritical(this,array,isCopy);
}
void ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode) {
functions->ReleasePrimitiveArrayCritical(this,array,carray,mode);
}
也是JDK1.2出来的,为了增加直接传回指向Java数组的指针而加入的函数,同样的也会有同GetStringCritical的死锁问题。
处理对象类型数组
示例:
java端:
public class TestMain {
public int[] intarr={1,2,3,4};
public native void getjni();
public static void main(String[] args) {
// TODO Auto-generated method stub
System.loadLibrary("ConsoleApplication");
TestMain j = new TestMain();
j.getjni();
}
}
c/c++:
JNIEXPORT void JNICALL Java_com_cn_TestMain_getjni
(JNIEnv * env, jobject obj){
jclass cls=env->GetObjectClass(obj);
jfieldID fid_arrays=env->GetFieldID(cls,"intarr","[I");
jintArray jint_arr=(jintArray)env->GetObjectField(obj,fid_arrays);
jint* int_arr=env->GetIntArrayElements(jint_arr,NULL);
jsize len=env->GetArrayLength(jint_arr);
for(jsize i=0;i<len;i++){
cout<<int_arr[i]<<endl;
}
env->ReleaseIntArrayElements(jint_arr,int_arr,JNI_ABORT);
};
JNI没有提供直接把Java的对象类型数组直接转到c++中的jobject[]数组的函数,而是直接通过
jobject GetObjectArrayElement(jobjectArray array, jsize index) {
return functions->GetObjectArrayElement(this,array,index);
}
void SetObjectArrayElement(jobjectArray array, jsize index,
jobject val) {
functions->SetObjectArrayElement(this,array,index,val);
}
这样的函数来对Java的Object[]数据进行操作的。