私はネイティブメソッドを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