Search code examples
javadlljava-native-interface

JNI and DLL: Two way interaction (callback)


I'm developing a dll library for java use. I am experience java programmer. I have seen tutorial on how to use JNI and how to create a DLL library, but I can't find a good resource on how to let the dll interact with the java program like a two way street.

This is a sample scenario:

In the java app, it will call a native method callNativeMethod(), then in the dll callNativeMethod(), there will be an event on which it will need to call a method on the java app which is callJavaMethod(). How can I call the callJavaMethod() from the dll.

Please suggest how can I implement it and possibly if you have a good tutorial resource for it.

//Edit: So the correct term is a callback. =P


Solution

  • First you can get class reference by using

     FindClass 
    

    After that, you can get function id of functions of that class using

     GetStaticMethodID and GetMethodID
    

    Then running with

     CallStaticVoidMethod, CallStaticIntMethod, and CallStaticObjectMethod...
    

    All these needs to be with a JVM(if you already have derived header and c++ from javah.exe, you already have this so could skip JVM creation),

    JNIEnv* create_vm(JavaVM ** jvm) {
    
        JNIEnv *env;
        JavaVMInitArgs vm_args;
    
        JavaVMOption options; 
        //Path to the java source code     
        options.optionString = "-Djava.class.path=D:\\Java Src\\TestStruct"; 
        vm_args.version = JNI_VERSION_1_6; //JDK version. This indicates version 1.6
        vm_args.nOptions = 1;
        vm_args.options = &options;
        vm_args.ignoreUnrecognized = 0;
    
        int ret = JNI_CreateJavaVM(jvm, (void**)&env, &vm_args);
        if(ret < 0)
            printf("\nUnable to Launch JVM\n");       
        return env;
    }
    

    Example(c++):

     jclass clas;
     clas=FindClass("projectHello/helloWorldClass");
     jmethodID meth;
     meth = env->GetStaticMethodID(clas, "sayHello", "(I)V");
     env->CallStaticVoidMethod(clas, meth,val); //val is (I) ---> parameter. Return type V ---->void
    

    If you are not shure what lies behind a class, you should check for errors such as

     if (env->ExceptionCheck()) {return ERR_GET_STATIC_METHOD_FAILED;}