java — JNI GetShortArrayElements завершается ошибкой с SIGSEGV SEGV_ACCERR

Я создал буфер в управляемом коде:

var nativeBuffer = ShortArray(bufferSize)

Это код Котлина, но согласно документация stdlib, этот синтаксис фактически является оберткой, которая возвращает short [],

Затем я хотел бы написать в этот буфер из C ++, используя JNI:

JNIEXPORT void JNICALL Java_package_class_name_readNext
(JNIEnv * env, jclass clazz, jshortArray javaArray)
{
jboolean * isCopy;
short * targetArray = env->GetShortArrayElements(javaArray, isCopy);

// Do stuff to targetArray
}

Проблема в том, что GetShortArrayElements вызов всегда приводит к сбою со следующим надгробием:

11-07 21:23:53.610 86-86/? I/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
11-07 21:23:53.610 86-86/? I/DEBUG: Build fingerprint: 'generic/vbox86p/vbox86p:5.1/LMY47D/buildbot06092001:userdebug/test-keys'
11-07 21:23:53.610 86-86/? I/DEBUG: Revision: '0'
11-07 21:23:53.610 86-86/? I/DEBUG: ABI: 'x86'
11-07 21:23:53.610 86-86/? I/DEBUG: pid: 28339, tid: 28477, name: Thread-282  >>> <package-name> <<<
11-07 21:23:53.610 86-86/? I/DEBUG: signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0xb3bcfacb
11-07 21:23:53.613 86-86/? I/DEBUG:     eax b3bcfacb  ebx b3ffcaa4  ecx a2497000  edx b426e480
11-07 21:23:53.613 86-86/? I/DEBUG:     esi a2497000  edi b3fff440
11-07 21:23:53.613 86-86/? I/DEBUG:     xcs 00000073  xds 0000007b  xes 0000007b  xfs 000000e7  xss 0000007b
11-07 21:23:53.613 86-86/? I/DEBUG:     eip b3dcd69c  ebp 9f5a2968  esp 9f5a2880  flags 00210282
11-07 21:23:53.613 86-86/? I/DEBUG:     #00 pc 002e069c  /system/lib/libart.so (short* art::JNI::GetPrimitiveArray<_jshortArray*, short, art::mirror::PrimitiveArray<short> >(_JNIEnv*, _jshortArray*, unsigned char*)+572)
11-07 21:23:53.613 86-86/? I/DEBUG:     #01 pc 0010cdad  /system/lib/libart.so (art::CheckJNI::GetShortArrayElements(_JNIEnv*, _jshortArray*, unsigned char*)+125)

javaArray не является нулевым (обычно адрес, такой как -1621480864) и nativeBuffer является статической переменной, поэтому вряд ли будет GC’ed. Такое поведение наблюдается на экземплярах Genymotion (x86) и на устройствах ARM, но я тестировал только на Android 5.0+. Что еще я мог пропустить?

1

Решение

К сожалению, вы не используете isCopy аргумент правильно. Так должно быть:

jboolean isCopy;
jshort* targetArray = env->GetShortArrayElements(javaArray, &isCopy);

То есть, isCopy является «параметром out» (для использования языка C #).

Если вам все равно, targetArray связан с javaArrayВы также можете пройти nullptr вместо этого, вот так:

jshort* targetArray = env->GetShortArrayElements(javaArray, nullptr);
3

Другие решения

Целевой массив должен быть jshort скорее, чем короткая.

Также вам нужно пройти isCopy с помощью ссылки & вместо по значению.

Больше информации здесь:
http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#wp17382

3

По вопросам рекламы [email protected]