当从非UI线程调用时,通过Android NDK调用本机代码会导致致命信号11(SIGSEGV)崩溃
我正在使用活动中的NDK调用我的本机C库。从主UI线程调用时,一切正常(但UI被阻止)。从新线程(使用当从非UI线程调用时,通过Android NDK调用本机代码会导致致命信号11(SIGSEGV)崩溃,android,multithreading,android-ndk,Android,Multithreading,Android Ndk,我正在使用活动中的NDK调用我的本机C库。从主UI线程调用时,一切正常(但UI被阻止)。从新线程(使用new thread()创建或使用AsyncTask创建)调用时,它会在logcat中出现“a/libc(32044):0x77f1a000处的致命信号11(SIGSEGV)、线程32624(线程-56564)”错误 我在图书馆打了两个电话。第一个调用执行ok。第二个调用在GetByteArrayRegion语句上崩溃: JNIEXPORT void JNICALL Java_com_mycom
new thread()
创建或使用AsyncTask
创建)调用时,它会在logcat中出现“a/libc(32044):0x77f1a000处的致命信号11(SIGSEGV)、线程32624(线程-56564)”错误
我在图书馆打了两个电话。第一个调用执行ok。第二个调用在GetByteArrayRegion语句上崩溃:
JNIEXPORT void JNICALL Java_com_mycompany_myproduct_library_process_data(JNIEnv *env, jobject obj, jbyteArray jBuffer) {
int len = (*env)->GetArrayLength(env, jBuffer);
unsigned char buffer[len];
(*env)->GetByteArrayRegion(env, jBuffer, 0, len, buffer); // crash
process_buffer(buffer);
}
我尝试在单独的线程中运行的原因是为了在执行期间不阻塞UI并显示进度条
非常感谢您的帮助。正如@BitBank正确指出的那样,buffer[len]的声明不会分配内存,而未分配的内存用于缓冲区(可能在堆栈上)。这只有在使用不同的线程时才对我可见。 改成
unsigned char *buffer;
buffer = malloc(len);
(*env)->GetByteArrayRegion(env, jBuffer, 0, len, buffer);
process_buffer(buffer);
free(buffer);
已解决问题。这两个呼叫是否有可能重叠?这意味着两个线程同时调用JNI方法?另外,请发布GetByteArrayRegion的代码。不,调用是顺序的。首先调用在磁盘上创建新文件,然后调用向其中添加数据(这将被多次调用,也是顺序调用)。我没有GetByteArrayRegion的代码,它是在jni.hIs中定义的,它只是我,或者buffer[]变量的声明没有意义,因为它是在运行时初始化的本地堆栈变量?尝试将其更改为buffer=malloc(len),然后在完成时释放(buffer)。不仅仅是你,你实际上解决了我的问题!我想知道为什么这样做会奏效。也许可以将你的解决方案分享给子孙后代。