Jni 能夠經過JNIEnv提供的方法,對傳過來的Java數組進行相應的操做。它提供了兩種函數:一種是操做Java的簡單型數組的,另外一種是操做對象類型數組的。 java
由於速度的緣由,簡單類型的Java數組,會做爲指向本地類型的指針暴露給本地代碼調用。所以,它們能做爲常規的數組存取。這個指針是指向實際的Java數組或者Java數組的拷貝的指針。另外,數組的佈置保證匹配本地類型。
在C/C++中,jintArray 不能用下標對其進行直接存取,必須用到JNI中提供的接口函數進行操做。 爲了存取Java簡單類型的數組,就要要使用GetXXXArrayElements函數(見表),XXX表明了數組的類型。這個函數把Java數組當作參數,返回一個指向對應的本地類型的數組的指針。 數組
函數 | Java 數組類型 | 本地類型 |
GetBooleanArrayElements | jbooleanArray | jboolean |
GetByteArrayElements | jbyteArray | jbyte |
GetCharArrayElements | jcharArray | jchar |
GetShortArrayElements | jshortArray | jshort |
GetIntArrayElements | jintArray | jint |
GetLongArrayElements | jlongArray | jlong |
GetFloatArrayElements | jfloatArray | jfloat |
GetDoubleArrayElements | jdoubleArray | jdouble |
JNIEXPORT jint JNICALL Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr) { jint *carr; carr = (*env)->GetIntArrayElements(env, arr, false); //得到Java數組arr的引用的指針 if(carr == NULL) { return 0; /* exception occurred */ } jint sum = 0; for(int i=0; i<10; i++) { sum += carr[i]; } (*env)->ReleaseIntArrayElements(env, arr, carr, 0); return sum; }
在C/C++代碼中,int類型的數組對應JNI中的jintArray,而相似字符串數組這種類型的,在Jni裏對應的使用 jobjectArray 來聲明,下面是存取訪問 jobjectArray 的方法簡介: 函數
GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index) array: a reference to the java.lang.Object array from which the element will be accessed. index: the array index 功能:返回對應索引值的object.返回的是一個數組元素的值。 SetObjectArrayElement(JNIEnv* env, jobjectArray array, jsize index, jobject value) array: a reference to an array whose element will be accessed. index: index of the array element to be accessed. value: the new value of the array element. 功能:用來設置對應索引元素的值。
GetIntArrayRegion(array,jsize start,jsize len,*buf) array:a reference to an array whose elements are to be copied. start:the starting index of the array elements to be copied. len: the number of elements to be copied. buf: the destination buffer. 功能:把jintArray中的元素複製到buffer中。 SetIntArrayRegion(array,jsize start,jsize len,*buf) array:a reference to a primitive array to which the elements to be copied. start:the starting index in the primitive array. len:the number of elements to be copied. buf:the source buffer. 功能:把buf中的元素copy到jintArray中去。
使用SetXXXArrayRegion與GetXXXArrayRegion就是以複製的方式設置與取出Array數組中的某個值。 spa
在Jni中,二維數組和String數組都被視爲object數組,由於Array和String被視爲object。下面例子實現了構造並返回一個二維int數組: 指針
JNIEXPORT jobjectArray JNICALL Java_ObjectArrayTest_initInt2DArray(JNIEnv *env, jclass cls, int size) { jobjectArray result; jclass intArrCls = (*env)->FindClass(env, "[I"); //int數組的class result = (*env)->NewObjectArray(env, size, intArrCls, NULL); //二維int數組的實例 for (int i = 0; i < size; i++) { //初始化 jint tmp[256]; /* make sure it is large enough! */ for(int j = 0; j < size; j++) { tmp[j] = i + j; } jintArray iarr = (*env)->NewIntArray(env, size); (*env)->SetIntArrayRegion(env, iarr, 0, size, tmp); //將tmp複製到iarr中 (*env)->SetObjectArrayElement(env, result, i, iarr); (*env)->DeleteLocalRef(env, iarr); } return result; }
最後得特別說明一下,當你使用對數組進行訪問後,要確保調用相應的ReleaseXXXArrayElements函數,參數是對應Java數組和GetXXXArrayElements返回的指針,若是必要的話,這個釋放函數會複製你作的任何變化(這樣它們就反射到java數組),而後釋放全部相關的資源,避免發生內存泄漏。 code
本文轉自Zhiweiofli's Blog,轉載請註明出處,謝謝。
對象