Re: JNI and GetFieldID
On 07/09/13 21:27, Borneq wrote:
U??ytkownik "Borneq" <borneq@antyspam.hidden.pl> napisa?? w wiadomo??ci
news:l0d1ak$5s5$1@node1.news.atman.pl...
=======> https://github.com/borneq/JNIdemo
Main problem: in this demo callback is not called by pointer to
function but only CallVoidMethod. But my library must be above other
library which uses callback by pointer to function. How do it?
If the callbacks are C, they will usually have a (void *) parameter to
pass context. (If they don't, I'd say they're shoite, or they're not
what one supposes they're for.) The context will have to include the
JNIEnv pointer at least, and the details of the Java callback.
Suppose that the library you're wrapping defines a callback:
typedef void foo_callback1(void *, int, const char *);
void foo_do_something(foo_obj *, foo_callback1 *cb, void *ctxt);
In Java, you define a corresponding callback interface:
package foo;
interface Callback1 {
void apply(int x, String s);
}
class Foo {
native void doSomething(Callback1 cb);
}
Back in C, you write a C callback which invokes a Java callback:
struct this_op_context {
JNIEnv *env;
jobject user;
};
static void my_callback(void *vctxt, int x, const char *s)
{
struct this_op_context *ctxt = vctxt;
jstring str = ctxt->env->NewStringUTF(s);
jclass cls = ctxt->env->FindClass("foo/Callback1");
jmethodID mid = ctxt->env->GetMethodID(cls, "apply", "(ILjava/lang/String;)V");
ctxt->env->CallVoidMethod(env->user, (jint) x, str);
// Clean up?
...
}
....and set it up to be invoked:
JNIEXPORT void JNICALL Java_foo_Foo_doSomething
(JNIEnv *env, jobject jObj1, jobject cb)
{
struct this_op_context ctxt = {
.env = env,
.user = cb;
};
// Extract/create foo structures from data in jObj1.
foo_obj *foo = ...;
foo_do_something(foo, &my_callback, &ctxt);
// Clean up?
...
}
That's assuming you don't need any C foo structures to persist beyond
this call, and no callback will occur after foo_do_something has
returned. Otherwise, you have to start thinking about memory management
of the foo structures and the callback contexts, and whether you want
them to map to Java objects, and how to do that mapping, etc.
I can think of straight-forward ways to map (say) a foo.Foo to a
foo_obj, but I'm not so sure about how you'd manage a struct
this_op_context. I'd also be concerned about whether the JNIEnv pointer
stored in the struct was even valid after returning from the native call.
--
ss at comp dot lancs dot ac dot uk