JNI - Listener in C ++ / Java - is it possible to create Java objects in C ++ and use them as parameters

Is it possible to use the following 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
}

Is it possible

  • register object Listeneron dll (it should be no problem as far as i found out)
  • to create an instance of an object Infoin c / C ++ code and use it as a parameter to call Listener.eventOccured(Info...)?

Or what would be a good way to implement a listener that receives some information from a DLL?

In my case, we have a dll that does some work. We call this dll from java. Now we want to attach the listener to the DLL in order to push us to some progress information. The above example is the part of the listener that I don’t know if it is possible with respect to calling the constructor of the Java constructor from c / C ++.

, , , - , .

, c/++, :)

+4
1

: , , Java JNI.

jni- , . http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html

javap -s javah, java- jni 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 );
}
+5

Source: https://habr.com/ru/post/1533698/


All Articles