1. 程式人生 > >JNI/NDK開發指南--訪問陣列

JNI/NDK開發指南--訪問陣列

直接上程式碼:

    void testFunc(){
        int[] indexs = new int[]{4, 5, 6}; 
        int[] ages = new int[]{3,4,5,6,7,8};
        int sum = sumArray(ages);
        Log.d(TAG, "sum="+sum);
        int sum2 = sumArray2(indexs);
        Log.d(TAG,"sum2="+sum2);

        int[][] arr = initInt2DArray(3);
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                System.out.format("arr[%d][%d] = %d\n", i, j, arr[i][j]);
            }
        }
    }

    public native int sumArray(int[] iarr);

    public native int sumArray2(int[] iarr);

    private native int[][] initInt2DArray(int size);

以下是c++程式碼片段


JNIEXPORT jint JNICALL Java_com_test_myjnitest_MainActivity_sumArray(
        JNIEnv *env, jobject jthis, jintArray jintArray1) {
    if (NULL == env || NULL == jthis || NULL == jintArray1) {
        return 0;
    }

    jint i, sum = 0;
    jint *c_arrays;
    jint array_length;
    //1. 獲取陣列長度
    array_length = env->GetArrayLength(jintArray1);
    //2. 根據陣列長度和陣列元素的資料型別申請存放java陣列元素的緩衝區
    c_arrays = (jint *) malloc(sizeof(jint) * array_length);
    //3. 初始化緩衝區
    memset(c_arrays, 0, sizeof(jint) * array_length);
    //4. 拷貝Java陣列中的所有元素到緩衝區中
    env->GetIntArrayRegion(jintArray1, 0, array_length, c_arrays);
    LOGD("########## array_length =%d", array_length);
    for (i = 0; i < array_length; i++) {
        sum += c_arrays[i]; //5. 累加陣列元素的和
        LOGD("########## index =%d, arrays=%d,sum=%d", i, c_arrays[i], sum);
    }
    free(c_arrays); //6. 釋放儲存陣列元素的緩衝區

    return sum;
}

JNIEXPORT jint JNICALL Java_com_test_myjnitest_MainActivity_sumArray2(
        JNIEnv *env, jobject jthis, jintArray jintArray1) {
    if (NULL == env || NULL == jthis || NULL == jintArray1) {
        return 0;
    }
    jint i, sum = 0;
    jint *c_array;
    jint array_length;

    // 可能陣列中的元素在記憶體中是不連續的,JVM可能會複製所有原始資料到緩衝區,然後返回這個緩衝區的指標
    c_array = env->GetIntArrayElements(jintArray1, NULL);

    if (NULL == c_array) {
        return 0; // JVM複製原始資料到緩衝區失敗
    }

    array_length = env->GetArrayLength(jintArray1);

    for (i = 0; i < array_length; ++i) {
        sum += c_array[i];
        LOGD("########## index =%d, arrays=%d,sum=%d", i, c_array[i], sum);
    }

    env->ReleaseIntArrayElements(jintArray1, c_array, 0); // 釋放可能複製的緩衝區

    return sum;
}

JNIEXPORT jobjectArray JNICALL Java_com_test_myjnitest_MainActivity_initInt2DArray(
        JNIEnv *env, jobject jthis, jint size) {

    if (NULL == env || NULL == jthis) {
        return 0;
    }

    jobjectArray result;
    jclass clsIntArray;
    jint i,j;
    // 1.獲得一個int型二維陣列類的引用
    clsIntArray = env->FindClass("[I");
    if (clsIntArray == NULL) {
        return NULL;
    }
    // 2.建立一個數組物件(裡面每個元素用clsIntArray表示)
    result = env->NewObjectArray(size,clsIntArray,NULL);
    if (result == NULL) {
        return NULL;
    }

    // 3.為陣列元素賦值
    for (i = 0; i < size; ++i){
        jint buff[256];
        jintArray intArr = env->NewIntArray(size);
        if (intArr == NULL) {
            return NULL;
        }

        for (j = 0; j < size; j++) {
            buff[j] = i + j;
        }
        env->SetIntArrayRegion(intArr, 0,size,buff);
        env->SetObjectArrayElement(result, i, intArr);
        env->DeleteLocalRef(intArr);
    }

    return result;
}