Marl
Marl

Reputation: 1504

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

Upvotes: 1

Views: 993

Answers (2)

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 135992

This is an example of how to call a Java method

void callback(int depth) {
   ...
}

form C code

JNIEXPORT void JNICALL
Java_Callbacks_nativeMethod(JNIEnv *env, jobject obj, jint depth) {
  jclass cls = (*env)->GetObjectClass(env, obj);
  jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "(I)V");
  if (mid == 0)
    return;
  printf("In C, depth = %d, about to enter Java\n", depth);
  (*env)->CallVoidMethod(env, obj, mid, depth);
  printf("In C, depth = %d, back from Java\n", depth);
}

it's from here http://journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/method.html

Upvotes: 1

huseyin tugrul buyukisik
huseyin tugrul buyukisik

Reputation: 11910

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

Upvotes: 1

Related Questions