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 -s
和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/javah html的
以下是您将要做的事情的示例。 我还没有测试过,所以只需将它作为编写自己的参考。 注意:请注意包装符号(我假设没有包装)和例外。 任何JNI调用都会发生exception( env->...
),因此请查看有关如何处理exception的文档( 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 ); }