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

以下是否适用于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 } 

是否有可能

  • 在dll上注册一个Listener对象(据我所知,应该没问题)
  • 在c / c ++代码中实例化一个Info对象,并将其用作调用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

您还将使用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调用都会发生exception( env->... ),因此请查看有关如何处理exception的文档( ExceptionCheckExceptionDescribeExceptionClear )。

 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 ); }