True C/C++ callback handling in Jni
3 posts in topic
Flat View  Flat View
TOPIC ACTIONS:
 

Posted By:   mark_lassche
Posted On:   Thursday, July 5, 2001 09:38 AM

True C/C++ callback handling in Jni In all jni examples callback methods are always 'faked'. The actual callback is initiated from java, ie: public class foo { native void init(); native void nativecallback(); public void callback() { System.out.println("oh boy look we're in java now !!!"); } main() { init(); nativecallback(); } This works but I feel its faking because callbacks are usualy (as in the case I'm working on) initiated from the native library rather than from java. Ie #include #include "someapi.h" BOOL callback(STRUCTX info) { //    More>>
True C/C++ callback handling in Jni

In all jni examples callback methods are always 'faked'. The actual callback is initiated from java, ie:

			public class foo {
			
native void init();
native void nativecallback();

public void callback() {
System.out.println("oh boy look we're in java now !!!");
}

main() {
init();
nativecallback();
}


This works but I feel its faking because callbacks are usualy (as in the case I'm working on) initiated from the native library rather than from java. Ie

			
#include
#include "someapi.h"

BOOL callback(STRUCTX info) {
// do some important work
}

void main() {
someapi_init_call();
// wait for the callbacks now
}


When trying to couple the callback to java using jni, I tried the following (left out most details but you'll get the idea).

			


#include
#include "someapi.h"

jobject global_object;
env *global_env;

BOOL callback(STRUCTX info) {
// do some important work
methodid =(*global_env)->GetMethodID(*global_env, global_object, "javaCallback", "()V");

(*global_env)->CallVoidMethod(*global_env, global_object, methodid);
}

JNIEXPORT void JNICALL init(JNIEnv *env, jobject obj) {

init_native_api();
global_env = env;
global_object= (*env)->NewGlobalRef(env, class) ;
}


When executing this, the first callback goes fine, I get to see the 'we're in java now' equivalent without problems. However the second time I get the c counterpart of a null pointer exception. Why this occurs or what is not really clear. I'd like to see an example of how 'true callbacks' can be handled.

   <<Less

Re: True C/C++ callback handling in Jni

Posted By:   James_Easter  
Posted On:   Tuesday, February 12, 2002 11:28 AM

Install cygwin to get gcc, dllwrap and pthreads capability: http://sources.redhat.com/cygwin/


GCC doesn't have a __int64 built-in so use "long long" instead. Edit C:/jdk1.3.1/include/win32/jni_md.h


Replace the segment:
typedef long jint;
typedef __int64 jlong;
with:
typedef long jint;
#ifdef __GNUC__
typedef long long jlong;
#else
typedef __int64 jlong;
#endif


JavaTest.java


class JavaTest {
private boolean hasSecondaryThreadCalledBack = false;

public native void nativeMethod();

static {
System.loadLibrary("LibTest");
}
public static void main(String[] args) {
System.out.print("Primary thread running");
JavaTest javaTest = new JavaTest();
javaTest.nativeMethod();
while(!javaTest.hasSecondaryThreadCalledBack)
System.out.print(".");
System.out.println("Test complete");

}
private void callback(int test) {
System.out.println("Callback test parameter = " + test);
hasSecondaryThreadCalledBack = true;
}
}



CTest.c


#include
#include
#include "JavaTest.h"
JavaVM *jvm;
jobject gObject;
JNIEXPORT void JNICALL Java_JavaTest_nativeMethod(JNIEnv *env, jobject obj) {
jint result;
int threadId;
pthread_t aThread;
result = (*env)->GetJavaVM(env, &jvm);
gObject = (*env)->NewGlobalRef(env, obj);
threadId = pthread_create(&aThread, NULL, functionTest, NULL);
return;
}
void *functionTest() {
JavaVMAttachArgs args;
JNIEnv* env;
jint result;
jclass cls;
jmethodID mid;
args.version= JNI_VERSION_1_2;
args.name="user";
args.group=NULL;
/* Make sure you flush */
printf("
Secondary thread attaching to primary thread and executing callback
");
result=(*jvm)->AttachCurrentThread(jvm, (void **)&env, &args);
cls = (*env)->GetObjectClass(env, gObject);
mid = (*env)->GetMethodID(env, cls, "callback", "(I)V");
(*env)->CallVoidMethod(env, gObject, mid, 999);
result = (*jvm)->DetachCurrentThread(jvm);
return NULL;
}



Open a cygwin console

Note: gcc and dllwrap are part of the cygwin installation


$ javac JavaTest.java

$ javah JavaTest

$ gcc -g -O2 -c -Ic:/jdk1.3.1/include -Ic:/jdk1.3.1/include/win32 CTest.c

$ dllwrap --output-def LibTest.def --add-stdcall-alias -o LibTest.dll -s CTest.o


$ java JavaTest

Primary thread running..............................................

Secondary thread attaching to primary thread and executing callback

Callback test parameter = 999

Test complete

Re: True C/C++ callback handling in Jni

Posted By:   Ori_Argov  
Posted On:   Sunday, February 3, 2002 11:22 AM

Hi Mark,
I have been trying to find "real" callbacks in JNI just as you write here. I also thought of the solution you mentioned here, but I think there is a problem with it which might explain your nullpointer crash.
You keep a pointer to your JVM in your C++ DLL, but I think that pointer might become invalid with time, and then when you try to access *global_env the crash happens.
I'm no expert on this by any means, just a thought...
BTW, If you do find an answer to this, I'd be very happy to know.

Re: True C/C++ callback handling in Jni

Posted By:   Sreenivasulu_Gali  
Posted On:   Wednesday, December 12, 2001 10:29 PM

Hi Mark,

This is srinivas..i need the sample code to call the java method from the c function...Which is urgent to me....

Pls send to me as soon as possible to
gali123@hotmail.com

Thanks advance
by
Srini
About | Sitemap | Contact