I have a JNI call from android, where I send data (bytes, width and height) for image processing. The function works fine when executing from the main android thread. I want to call from another thread, to avoiding blocking UI, but when I do that the JNI throws a memory error. If I call from main thread, works fine.
The error is thrown from env->GetIntArrayRegion(...).
extern "C"
JNIEXPORT jobjectArray JNICALL
Java_topcodes_TopCodesScanner_searchTopCodesNative(JNIEnv *env, jobject thiz, jint image_width,
jint image_height, jintArray image_data) {
auto image_data_size = env->GetArrayLength(image_data);
jint image_data_buf[image_data_size];
// error in this line
env->GetIntArrayRegion(image_data, 0, image_data_size, image_data_buf);
The way I'm creating the new threads is this:
private val executorService by lazy { Executors.newFixedThreadPool(4) }
override fun analyze(image: ImageProxy) {
executorService.submit { // if comment, works fine
try {
val blocks = findBlocks(image)
handler.post { listener(blocks); }
} finally {
image.close()
}
} // if comment, works fine
}
Here is the stack trace.
memcpy 0x0000007f8f938d9c
art::JNI::*GetIntArrayRegion(_JNIEnv, _jintArray*, int, int, int*) 0x0000007f8bddcea0
art::CheckJNI::GetPrimitiveArrayRegion(char const*, art::Primitive::Type, _JNIEnv*, _jarray*, int, int, void*) 0x0000007f8bbf07fc
<unknown> 0x0000007f750c0aec
<unknown> 0x0000007f750c0708
topcodes.TopCode[] topcodes.TopCodesScanner.searchTopCodesNative(int, int, int[]) 0x0000007f7844218c
art_quick_invoke_stub 0x0000007f8bbb6ca8
art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*) 0x0000007f8bbc5b80
artInterpreterToCompiledCodeBridge 0x0000007f8bf64574
bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x0000007f8bd3fc48
art::JValue art::interpreter::ExecuteGotoImpl<false, false>(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue) 0x0000007f8bb76e44
art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame*) 0x0000007f8bd1d9c4
artQuickToInterpreterBridge 0x0000007f8bfd4944
art_quick_to_interpreter_bridge 0x0000007f8bbc0a28
<unknown> 0x0000007f8bbc0b90
I've searched for similar questions. Thanks in advance.