如何创建静态 JNI 环境指针? [英] How to create static JNI Environment Pointer?

查看:20
本文介绍了如何创建静态 JNI 环境指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这里,我在 JAVA 中创建了一个类,其中有我必须从 C 文件调用的函数(回调).

Here I create a class in JAVA in which I have function (callback) which I must call from C file.

class DSMInitializeClassParameter {

    /**
     * Callback function for DSM Initialize.
     */
    public void DSMInitializeCallback( ) {

        // Write Message To Logs.
        System.out.println( "Dsm Initialize Callback called." );
    }
}

为此,我创建了必须调用的本地方法.

For that I have created native method which must be called.

public class DsmLibraryTest extends Activity {
     // Some code ....

     // Create a DSMInitializeClassParameter  class object.
     DSMInitializeClassParameter object = new DSMInitializeClassParameter();
     // Call native method with given object.
     nativeMethod( object );

     // Some code ....

     // Implementation of native method.
     public native int nativeMethod(DSMInitializeClassParameter classObject);
}

C 文件中,我有以下内容:

In C file I have following:

dsmResult_t dsmInitializeCall( dsmResult_t status, void * pUserData, dsmEvent_t * hEvent ) {

    (*env)->CallVoidMethod(env, classObject, mid);
}

JNIEXPORT jint JNICALL Java_com_Dsm_Test_DsmLibraryTest_nativeMethod(JNIEnv* env, jobject obj, jobject classObject) {
    // This function loads a locally-defined class. It searches the directories and zip
    // files specified by the CLASSPATH environment variable for the class with the specified name.
    jclass cls = (*env)->FindClass( env, "com/Dsm/Test/DSMInitializeClassParameter" );
    // Get java Method.
    jmethodID mid = (*env)->GetMethodID(env, cls, "DSMInitializeCallback", "()V");
    // If no method was found return -1;
    if( mid == NULL ) {
        return -1;
    }

    // Call DSM Initialize Callback Function and return value.
    return dsmInitialize( dsmInitializeCall, NULL );
}

你怎么看我想从 dsmInitializeCall 函数调用 (*env)->CallVoidMethod(env, classObject, mid); ,但是我怎么能调用如果我没有 envclassObjectmid 我尝试使用静态但它不起作用.

how you can see I want to call (*env)->CallVoidMethod(env, classObject, mid); from dsmInitializeCall function, but how I can call it if I have no env, classObject and mid I try with statics but it not work.

推荐答案

一般是 不安全 缓存 JNIEnv* 实例并继续使用它,因为它根据当前活动的线程而变化.您可以保存一个 JavaVM* 实例,它永远不会改变.在本机初始化函数中,调用 GetJavaVM 并将 JavaVM 指针的地址传递给它:

It's generally unsafe to cache a JNIEnv* instance and keep using it, as it varies depending on the currently active thread. You can save a JavaVM* instance, which will never change. In a native initializer function, call GetJavaVM and pass it the address of a JavaVM pointer:

static JavaVM *jvm;
JNIEXPORT void JNICALL Java_SomeClass_init(JNIEnv *env, jclass) {
    int status = (*env)->GetJavaVM(env, &jvm);
    if(status != 0) {
        // Fail!
    }
}

现在您可以使用 JavaVM* 获取当前的 JNIEnv*AttachCurrentThread:

Now you can use that JavaVM* to get the current JNIEnv* with AttachCurrentThread:

dsmResult_t dsmInitializeCall( dsmResult_t status, void * pUserData, dsmEvent_t * hEvent ) {
    JNIEnv *env;
    (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
    (*env)->CallVoidMethod(env, classObject, mid);
}

这篇关于如何创建静态 JNI 环境指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆