JNI - C++/Java 中的侦听器 - 是否可以在 C++ 中实例化 Java 对象并将其用作参数

2023-12-20

以下可以与 JNI 一起使用吗?

public NativeClass {

    static {
        System.loadLibrary("dll");
    }

    public static native void addListener(Listener listener);
}

public interface Listener {
    public void eventOccurred(Info info);
}

public Info {

    private final String s1;
    private final String s2;

    public Info(String s1, String s2);

    // ... getters for use in Java
}

是否有可能

  • 注册一个Listenerdll 上的对象(据我所知应该没问题)
  • 实例化一个Infoc/c++代码中的对象并用它作为调用的参数Listener.eventOccured(Info...)?

或者实现从 DLL 获取一些信息的侦听器的好方法是什么?

就我而言 - 我们有一个 dll 可以完成一些工作。我们从java调用这个dll。现在我们想给 dll 附加一个监听器,以便在工作时向我们推送一些进度信息。上面的例子是监听器部分,我不知道是否可以从c/c++构造函数调用Java构造函数。

提示在哪里可以找到描述答案的文档,那就太好了 - 我找不到可以回答我的问题的信息。

一小段代码,描述 c/c++ 部分将是锦上添花:)


简而言之,答案是肯定的,您可以通过 JNI 在本机层中保存、实例化和传递 Java 对象。

在 jni 文档中,您将找到可以为您执行此操作的函数。http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html

您还将使用javap -s and javah帮助查找在 jni 中使用的 java 方法签名并制作 jni 标头。看http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javap.html http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javap.html & http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javah.html http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javah.html

这是您将要做的事情的示例。我还没有测试过,所以只是将其用作自己编写的参考。注意:请注意包符号(我假设没有包)和异常。任何 JNI 调用都可能发生异常(env->...),所以查看有关如何处理异常的文档(ExceptionCheck, ExceptionDescribe, ExceptionClear).

JavaVM * savedVM = NULL;
JNIEXPORT void JNICALL Java_NativeClass_addListener(JNIEnv *env, jobject obj_instance, jobject listener_instance) 
{
   env->GetJavaVM( &savedVM );
   //save listener_instance for use later
   saved_listener_instance = listener_instance;
}

void doSomething()
{
    //Get current thread JNIEnv
    JNIEnv * ENV;
    int stat = savedVM->GetEnv((void **)&ENV, JNI_VERSION_1_6);
    if (stat == JNI_EDETACHED)  //We are on a different thread, attach
        savedVM->AttachCurrentThread((void **) &ENV, NULL);
    if( ENV == NULL )
        return;  //Cant attach to java, bail

    //Get the Listener class reference
    jclass listenerClassRef = ENV->GetObjectClass( saved_listener_instance );

    //Use Listener class reference to load the eventOccurred method
    jmethodID listenerEventOccured = ENV->GetMethodID( listenerClassRef, "eventOccurred", "(LInfo;)V" );

    //Get Info class reference
    jclass infoClsRef = ENV->FindClass( "Info" );

    //Create Info class
    jobject info_instance = ENV->NewObject( infoClsRef, ..... );//For you to fill in with your arguments

    //invoke listener eventOccurred
    ENV->CallVoidMethod( saved_listener_instance, listenerEventOccured, info_instance );

    //Cleanup
    ENV->DeleteLocalRef( info_instance );
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JNI - C++/Java 中的侦听器 - 是否可以在 C++ 中实例化 Java 对象并将其用作参数 的相关文章

随机推荐