JNI機能では、私は、Arrayは変更しないJavaコードから渡されたインプレース配列を変更したとき

イゴール:

私はネイティブメソッドをJavaからint配列を渡しています。そして、JNI関数内で私はGetIntArrayElementsでint型の配列へのポインタを作成した()と* isCopy引数として渡すJNI_FALSE。私は、これは元の配列のコピーを作成しないであろうと、私は場所で配列を変更できることを想定します。それから私はReleaseIntArrayElements()を使用し、ちょうどreleseバッファへのモード引数として渡すJNI_ABORT。しかし、それは動作しませんでした。

JNIのドキュメントから:

  • モード0:バックコンテンツをコピーして、elemsバッファを解放
  • モードJNI_COMMIT:バックコンテンツをコピーするが、elemsにバッファを解放しません。
  • モードJNI_ABORT:バック可能な変更をコピーせずにバッファを解放

私は完全に働いたReleaseIntArrayElementsで使用するモード「0」()しようとしたときに。私は、コンテンツをコピーバックされ、元の配列とモード「0」のコピーを作成しなかった原因が、私は理由を理解していません。

私は、JNIは常に元の配列のコピーを作成することとします。しかし、その後* GetIntArrayElementsでisCopy引数()その意味を失います。だから何が本当にこれで起こって?

THIS IS MY JNI FUCNTION

extern "C" JNIEXPORT jdouble JNICALL
Java_my_own_package_MainActivity_myFunction(
    JNIEnv *env,
    jobject /* this */, jintArray tbl) {
    jint *tblptr = env->GetIntArrayElements(tbl, JNI_FALSE);
    tblptr[0] = 0; //in-place change
    env->ReleaseIntArrayElements(tb1, tblptr, JNI_ABORT);
    return 0;
}
いくつかの名前:

あなたは誤用しましたjboolean *isCopyそれはあなたが実際に呼び出した後、検討すべき出力パラメータですenv->GetIntArrayElements(tbl, isCopy);それが返された場合はJNI_FALSE、その後のコピーが行われていません。

GCは、ある場所から別の場所に要素を移動することができますので、これは必要で予期しない、あなたは常に元のJava配列に変更をコピーする必要があります。あなたは、実際のJava配列のメモリ位置を知ることはありませんので。

おたくない場合はコピーは、おそらく探している作られているcritical方法のバージョン。ここでJNIドキュメントが言うことです:

これらの制限は、それは可能性が高いネイティブコードが> VM>がピニングをサポートしていない場合でも、配列のコピーされていないバージョンを取得することを確認します

これは、それがそうする可能性が高いですが、あなたがクリティカルセクションを保持しているとして、JVMが長いと、ガベージコレクションを無効にすることを意味するものではありません。

EMP。私の:

例えば、VMができる一時的に無効にガベージコレクションネイティブコードは、を介して得られた配列へのポインタを保持している場合GetPrimitiveArrayCritical

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=223187&siteId=1
おすすめ