NDK開発の配列操作

5307 ワード

JNIはJava配列を参照型として処理し,JNIはJava配列にアクセスして処理するために必要な関数を提供する.
次は一つ一つ見てみましょう.
1.配列を作成するには、NewArray関数を使用して、元のコードに配列インスタンスを作成します.ここでは、Int、Char、Booleanなどです.NewIntArrayなどです.これらの関数を使用する場合は、配列のサイズをパラメータとして指定する必要があります.次のコードを見てください.
まずjintArray配列を定義し、次にjint配列を定義し、jint配列の内容をjintArrayにコミットし、jintArrayに戻ります.
jintArray Java_com_example_jni_MainActivity_getIntArray(JNIEnv* env,
        jobject thiz) {
    jintArray javaArray;
    jint nativeArr[3] = {21,22,23};
    javaArray = (*env)->NewIntArray(env,3);
    (*env)->SetIntArrayRegion(env,javaArray,0,3,nativeArr);
    return javaArray;
}

NewString関数と同様に、メモリがオーバーフローした場合、NewArray関数はNULLを返し、ネイティブコード仮想マシンに異常放出があることを通知し、ネイティブコードが停止します.
2.配列要素JNIにアクセスするには、Java配列要素にアクセスする2つの方法があります.Java配列をC配列にコピーするか、配列要素に直接ポインタを与えることができます.この2つの方法をそれぞれ紹介します.
2.1レプリカの操作Java配列をC配列にコピーし、その配列を操作できます.次のコードを見て、Javaが配列を転送し、配列要素の和を計算して戻ります.
jint Java_com_example_jni_MainActivity_getSum(JNIEnv* env,
        jobject thiz,jintArray javaArray) {
    //  Java         
    jsize length = (*env)->GetArrayLength(env,javaArray);
    //    C  
    jint nativeArr[length];
    jint sum = 0;
    // Java      C   
    (*env)->GetIntArrayRegion(env,javaArray,0,length,nativeArr);
    int i;
    //  
    for(i=0;i<length;i++){
        sum+=nativeArr[i];
    }
    return sum;
}

オリジナルコードは、通常のC配列を使用するように配列要素を使用および変更できます.元のコード相が行った変更をJava配列にコミットする場合、SetArrayRegion関数を使用してC配列をJava配列にコピーできます.次のコードを見て、Javaが転送した配列の各要素に1を加えて、修正した配列を返します.
jintArray Java_com_example_jni_MainActivity_arrAdd1(JNIEnv* env,
        jobject thiz,jintArray javaArray) {
    //  Java         
    jsize length = (*env)->GetArrayLength(env,javaArray);
    //    C  
    // Java      C   
    jint nativeArr[length];
    (*env)->GetIntArrayRegion(env,javaArray,0,length,nativeArr);
    int i;
    //      
    for(i=0;i<length;i++){
        nativeArr[i]=nativeArr[i]+1;
    }
    // C   Java         
    (*env)->SetIntArrayRegion(env,javaArray,0,length,nativeArr);
    return javaArray;
}

2.2ダイレクトポインタの操作
生コードはGetArrayElements関数を用いて配列要素への直接ポインタを取得することができる.3番目のパラメータは、前回のブログで述べたように、isCopyという名前のオプションパラメータであり、呼び出し元に返されるC文字列アドレスがコピーを指すか、スタック内の固定オブジェクトを指すかを決定させる.
通常のC配列のように配列要素にアクセスして処理することができるため、JNIは要素にアクセスして処理する方法を提供していない.JNIは原生コードが切れたらこれらのポインタをすぐに解放しなければならない.そうしないとメモリオーバーフローの問題が発生し、原生コードはJNIが提供したReleaseArrayElements関数を使用してGetArrayElements関数が返したC配列を解放することができる.この関数には4つのパラメータがあり,4つ目は解放モードであり,以下の3つがある.
0:              
JNI_COMMIT:                ,            Java  。
JNI_ABORT                。

今回はCを用いて簡単な乗算を行い,Javaは配列を伝え,その配列の要素を蓄積して返す.
jint Java_com_example_jni_MainActivity_multiplication(JNIEnv* env,jobject thiz,jintArray javaArray){
    jint* nativeDirectArray;
    jboolean isCopy;
    jint result = 1;
    jsize length = (*env)->GetArrayLength(env,javaArray);
    nativeDirectArray = (*env)->GetIntArrayElements(env,javaArray,&isCopy);
    int i = 0;
    for(i=0;i<length;i++){
        result *= nativeDirectArray[i];
    }
    (*env)->ReleaseIntArrayElements(env,javaArray,nativeDirectArray,0);
    return result;
}

はい、配列操作についてはこれだけです.問題があれば、伝言討論を歓迎します.