Android NDK開發之數組類型的操做

Jni 能夠經過JNIEnv提供的方法,對傳過來的Java數組進行相應的操做。它提供了兩種函數:一種是操做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.
功能:用來設置對應索引元素的值。

Get/SetXXXArrayRegion函數說明

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

關於二維數組和String數組

在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,轉載請註明出處,謝謝。
對象

相關文章
相關標籤/搜索