JNI – Listener en C ++ / Java – es posible crear una instancia de objetos Java en c ++ y usarlos como parámetros

¿Se puede usar lo siguiente con 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 } 

Es posible que

  • registrar un objeto de Listener en una dll (no debería haber ningún problema, por lo que supe)
  • crear una instancia de un objeto Info en el código c / c ++ y usarlo como un parámetro para llamar a Listener.eventOccured(Info...) ?

¿O cuál sería una buena manera de implementar un oyente que obtiene información de una DLL?

En mi caso, tenemos un dll que hace algún trabajo. Llamamos a este dll de java. Ahora queremos adjuntar un oyente a la dll, para que nos empuje un poco de información de progreso mientras trabajamos. El ejemplo anterior es la parte de escucha, que no sé si es posible con respecto a la llamada del constructor a un constructor de Java desde c / c ++.

Una sugerencia donde encontrar una pieza de documentación, que describa la respuesta sería agradable, no pude encontrar información, que respondió a mi pregunta.

Un pequeño fragmento de código, que describe la parte c / c ++ sería la guinda del pastel 🙂

La respuesta corta es sí, puede retener, crear instancias y pasar objetos Java en una capa nativa a través de JNI.

En la documentación de jni, encontrará funciones que lo harán por usted. http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html

También usará javap -s y javah para ayudarlo a encontrar las firmas del método java para usar en jni y para hacer sus encabezados jni. Consulte http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javap.html y http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javah .html

Aquí hay una muestra de lo que vas a hacer. No lo he probado, así que solo úsalo como referencia para escribir el tuyo. Nota: tenga en cuenta las notaciones de paquetes (no asumí ningún paquete) y excepciones. Pueden ocurrir excepciones en cualquier llamada JNI ( env->... ), así que consulte la documentación sobre cómo tratar con las excepciones ( 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 ); }