В функции JNI при изменении массива в месте, которое было передано из Java коды Массив не изменяет

Игорь:

Я пропускание целочисленного массива из 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

рекомендация

отhttp://43.154.161.224:23101/article/api/json?id=223184&siteId=1
рекомендация