Reputation: 1504
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
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
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