creating a 'listener' on a native C device
Greetings,
I have posted something related to this in the thread "accessing a method through its mapping address". I thought I should generalise the problem a bit, so that others might benefit.
The general problem:
I have a device with an SDK written in C++. To access incoming data from the device, we wrote a JNI wrapper that would receive callbacks from the device, store the data, then allow us to make calls to retrieve it from Java. Much better would be if there were a way to have callbacks from its SDK go directly to our Java appliation. I've seen JNative (http://jnative.free.fr/SPIP-v1-8-3/), but it seems much more compliated than what I need here. Here's how we've tried to write this:
1. create an 'init' function, called from Java, which will open the connection to the device. Calling this will also give a pointer to the JVM, which we store.
2. when the sdk calls back, turn around and invoke a java method on the JVM we stored on the call to init.
Unfortunately, this doesn't quite work (or, rather, our implementation doesn't work!). We've tried to setup a *very* basic callback: the Java method takes only a single int as a param. The code for our C function is below. We get an Access Exception (way up in the stack) on our call to CallVoidMethod. Anyone out there do something like this before?
//Note: cached_jvm is the JVM object we received on the init, and TheObject is the jobject called on init:
void javaCallback() {
JNIEnv *env;
(cached_jvm)->AttachCurrentThread((void **)&env,NULL );
jclass cls =env->FindClass("com/merl/forlines/input/fingerworks/FingerWorksDeviceJNI");
javaMethod = (env)->GetMethodID(cls, "cliffCallback", "(I)V");
// '17' here is the value we're trying to pass to our method, which takes an
// int.
env->CallVoidMethod(TheObject, javaMethod, 17);
(cached_jvm)->DetachCurrentThread();
}

