2015-11-08 71 views
1

我創建了一個託管代碼的緩衝區:JNI GetShortArrayElements失敗SIGSEGV SEGV_ACCERR

var nativeBuffer = ShortArray(bufferSize) 

這是科特林代碼,但根據stdlib documentation,這句法實際上是一個返回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化。該行爲發生在Genymotion實例(x86)和ARM設備上,但我只針對Android 5.0+進行了測試。我還能錯過什麼?

回答

3

糟糕,您沒有正確使用isCopy參數。它應該是:

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

也就是說,isCopy是一個 「輸出參數」(使用C#行話)。

如果你不關心targetArray是否化名爲javaArray,你也可以通過nullptr代替,就像這樣:

jshort* targetArray = env->GetShortArrayElements(javaArray, nullptr); 
相關問題