0

I'm trying to use JSI and JNI in a React-Native app for sending ArrayBuffer without encoding data.

For this, I have a C++ function receiveDataFromCpp():

extern "C"
JNIEXPORT void JNICALL
Java_com_mymodule_rtnstreamstream_RTNStreamModule_nativeInstall(JNIEnv *env, jobject thiz, jlong jsi) {
    jsi::Runtime * runtime = reinterpret_cast<jsi::Runtime *>(jsi);
    jobject rtnstream_kt_module = env->NewGlobalRef(thiz);
    rtnstream::install(*runtime, env, rtnstream_kt_module);
}
jsi::Function getDeviceName = jsi::Function::createFromHostFunction(
        jsiRuntime,
        jsi::PropNameID::forAscii(jsiRuntime, "receiveDataFromCpp"),
        0,
        [&env, &rtnstream_kt_module](
                jsi::Runtime& runtime,
                const jsi::Value& thisValue,
                const jsi::Value* arguments,
                std::size_t count
        ) -> jsi::Value {
            if (count != 1 || !arguments[0].isObject()) {
                throw jsi::JSError(runtime, "Argument has to be an ArrayBuffer");
            }

            jsi::Object object = arguments[0].asObject(runtime);
            jsi::ArrayBuffer arrayBuffer = object.getArrayBuffer(runtime);

            size_t bufferSize = arrayBuffer.size(runtime);
            uint8_t* bufferData = arrayBuffer.data(runtime);

            jbyteArray jbyteArrayData = env->NewByteArray(bufferSize);
            env->SetByteArrayRegion(jbyteArrayData, 0, bufferSize, reinterpret_cast<const jbyte*>(bufferData));

            jclass java_class = env->FindClass("com/myModule/RTNStreamModule");

            jmethodID receiveDataFromCpp = env->GetMethodID(java_class, "receiveDataFromCpp", "([B)V"); // My kotlin method

            env->CallVoidMethod(rtnstream_kt_module, receiveDataFromCpp, jbyteArrayData);

            if (jbyteArrayData != nullptr) {
                env->DeleteLocalRef(jbyteArrayData); // Clean up
            }

            return jsi::Value(static_cast<double>(bufferSize));
        });

And from JS, just use receiveDataFromCpp(data);

It works the first time, but if I re-run receiveDataFromCpp, I get this crash error:

Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 26510 (mqt_v_js), pid 26432

I do not understand because I think the clean up is correct. Can anyone help me?

2
  • 2
    You need to start putting some breakpoints or print statements and see what's null. Check that bufferSize is valid and correct. Check that bufferData is not null. Check that rtnstream_kt_module is not null.
    – Brandon
    Commented Sep 24 at 16:00
  • 1
    Also, any JNIEnv *env value can not be safely used outside of the context of getting it from the JVM, whether or not it was passed as an argument from a JNI call or from attaching the current thread to the JVM. And JNIEnv *env values aren't the only values that can't safely be cached. This doesn't appear to be a complete example, so if you are caching values like that, you can't. Commented Sep 25 at 16:36

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.