JNI GetShortArrayElements失败,SIGSEGV SEGV_ACCERR

我在托管代码中创建了一个缓冲区:

var nativeBuffer = ShortArray(bufferSize) 

这是Kotlin代码,但是根据stdlib文档 ,这个语法实际上是一个返回short []的包装器。

然后我想使用JNI从C ++写入这个缓冲区:

 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 >>>  <<< 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 >(_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不是null(通常是一个类似于-1621480864的地址), nativeBuffer是一个静态variables,所以不可能被GC化。 该行为发生在Genymotion实例(x86)和ARM设备上,但是我只针对Android 5.0+进行了测试。 还有什么我可以错过?

糟糕,您没有正确使用isCopy参数。 它应该是:

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

也就是说, isCopy是一个“输出参数”(使用C#术语)。

如果不关心targetArray是否是targetArray的别名,那么也可以传递nullptr ,如下所示:

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

目标数组应该是jshort而不是简短的

你也需要通过引用isCopy使用而不是按值。

更多信息: http : //docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#wp17382