JNI 环境指针

2024-01-09

我有一个 Java 类,其中有一个必须从 C 代码调用的函数。 函数如下:

public void endTrial(){
    //Code
}

所以我在我的 C 文件中创建了以下代码:

JNIEXPORT void JNICALL package_endTrialJava();
JNIEXPORT void JNICALL package_endTrialJava(){
    jobject javaObjectRef = env->NewObject(javaClassRef, javaMethodRef);
    env->CallVoidMethod(javaObjectRef, javaMethodRef);
}

但是为了能够调用这个函数env变量,我创建了这个函数,每当我启动程序时都会调用该函数。

JNIEXPORT void JNICALL package_initJNI(JNIEnv* en, jobject ob)
{
    try {
        // LOGD("(JNI) [FluidMechanics] loadVelocityDataSet()");

        if (!App::getInstance())
            throw std::runtime_error("init() was not called");

        if (App::getType() != App::APP_TYPE_FLUID)
            throw std::runtime_error("Wrong application type");


        FluidMechanics* instance = dynamic_cast<FluidMechanics*>(App::getInstance());
        android_assert(instance);
        jclass dataClass = en->FindClass("fr/limsi/ARViewer/MainActivity");
        javaClassRef = (jclass) env->NewGlobalRef(dataClass);
        javaMethodRef = env->GetMethodID(javaClassRef, "endTrial", "()V");

        env = en ;
        obj = ob ;        

    } catch (const std::exception& e) {
        throwJavaException(env, e.what());
    }
}

我也在代码中声明了这些全局变量,以便对 initJNI() 的调用可以存储 JNIEnv 变量。

JNIEnv* env ;
jobject obj ;

但我的程序崩溃了,所以看起来存储JNIEnv变量不起作用。那有什么解决办法吗?


您不能/不应该存储JNIEnv指针。 is只对当前线程有效。
但你可以使用AttachCurrentThread得到一个JNIEnv当前线程的指针。
或者,如果您知道它已经附加,您可以使用GetEnv.
除此之外,您没有提到如何使用全局jobject obj但请记住,您需要注意这些参考文献保持足够长的有效时间。NewGlobalRef是要走的路。

未经测试:

JavaVM* g_jvm = 0;
JNIEXPORT void JNICALL package_initJNI(JNIEnv* en, jobject ob)
{
    ....
    // insted of the env store the VM
    en->GetJavaVM(&g_jvm);
    obj = en->NewGlobalRef(ob); // I don't think you need this
    // and at some point you must delete it again
    ....
}

JNIEXPORT void JNICALL package_endTrialJava(){
    JNIEnv* env;
    g_jvm->AttachCurrentThread(&env, NULL); // check error etc
    jobject javaObjectRef = env->NewObject(javaClassRef, javaMethodRef);
    // this line makes not much sense. I think you don't need it if you use the global
    // with the global it would be more like this
    env->CallVoidMethod(obj javaMethodRef);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JNI 环境指针 的相关文章

随机推荐