处理数组
数组分为两类: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[]数据进行操作的。