Я пропускание целочисленного массива из Java для нативного метода. Затем в функции JNI Я создал указатель на целочисленный массив с GetIntArrayElements () и передать в качестве аргумента * isCopy JNI_FALSE. Я полагал, что это не будет создавать копию исходного массива, и я мог бы изменить массив на месте. Затем я использую ReleaseIntArrayElements () и передать в качестве аргумента режим JNI_ABORT только relese буфера. Но это не сработало.
Из JNI документации:
- Режим 0: скопировать обратно содержание и освободить elems буфер
- Режим JNI_COMMIT: скопировать обратно содержание, но не освободить elems буфер
- Режим JNI_ABORT: освободить буфер без копирования обратно возможных изменений
То, когда я попытался в режим использования «0» в ReleaseIntArrayElements (), который работал отлично. Но я не понимаю, почему, потому что я не создал копию исходного массива и режим «0» копирует обратно содержимое.
Я полагаю, что JNI всегда создает копию исходного массива. Но тогда * isCopy аргумент в GetIntArrayElements () теряет свой смысл. Так что на самом деле происходит с этим?
ЭТО МОЯ 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. Мой:
Например, виртуальная машина может временно отключить сбор мусора , когда машинный код держит указатель на массив , полученный с помощью
GetPrimitiveArrayCritical