JNI - C++/Java中的监听器 - 可以在c ++中实例化Java对象并将它们用作参数

Kai*_*hel 4 c c++ java dll java-native-interface

以下是否可用于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
}
Run Code Online (Sandbox Code Playgroud)

是否有可能

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

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

在我的情况下 - 我们有一个dll做一些工作.我们从java中调用这个dll.现在我们想要将一个监听器附加到dll,以便在工作时向我们提供一些进度信息.上面的例子是监听器部分,我不知道是否有可能从c/c ++开始对构造函数调用Java构造函数.

一个提示在哪里找到一份文档,描述答案会很好 - 我找不到信息,这回答了我的问题.

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

Sam*_*ain 5

简短的回答是肯定的,您可以通过JNI在本机层中保存,实例化和传递Java对象.

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

您还将使用javap -sjavah帮助查找用于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/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 );
}
Run Code Online (Sandbox Code Playgroud)