Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #25244

Re: JNI and GetFieldID

From Steven Simpson <ss@domain.invalid>
Newsgroups comp.lang.java.programmer
Subject Re: JNI and GetFieldID
Date 2013-09-08 10:24 +0100
Organization A noiseless patient Spider
Message-ID <7cstfa-3nc.ln1@s.simpson148.btinternet.com> (permalink)
References <l0a6jn$9t4$1@node1.news.atman.pl> <gb2pfa-s33.ln1@s.simpson148.btinternet.com> <l0d1ak$5s5$1@node1.news.atman.pl> <l0g277$75f$1@node1.news.atman.pl>

Show all headers | View raw


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

Back to comp.lang.java.programmer | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

JNI and GetFieldID "Borneq" <borneq@antyspam.hidden.pl> - 2013-09-05 17:05 +0200
  Re: JNI and GetFieldID Mark <i@dontgetlotsofspamanymore.invalid> - 2013-09-06 10:25 +0100
  Re: JNI and GetFieldID Steven Simpson <ss@domain.invalid> - 2013-09-06 16:36 +0300
    Re: JNI and GetFieldID "Borneq" <borneq@antyspam.hidden.pl> - 2013-09-06 18:53 +0200
      Re: JNI and GetFieldID "Borneq" <borneq@antyspam.hidden.pl> - 2013-09-06 20:44 +0200
        Re: JNI and GetFieldID Steven Simpson <ss@domain.invalid> - 2013-09-06 22:34 +0300
          Re: JNI and GetFieldID "Borneq" <borneq@antyspam.hidden.pl> - 2013-09-06 23:06 +0200
      Re: JNI and GetFieldID "Borneq" <borneq@antyspam.hidden.pl> - 2013-09-07 22:27 +0200
        Re: JNI and GetFieldID Steven Simpson <ss@domain.invalid> - 2013-09-08 10:24 +0100
          Re: JNI and GetFieldID "Borneq" <borneq@antyspam.hidden.pl> - 2013-09-08 12:29 +0200
            Re: JNI and GetFieldID "Borneq" <borneq@antyspam.hidden.pl> - 2013-09-08 22:45 +0200
            Re: JNI and GetFieldID Steven Simpson <ss@domain.invalid> - 2013-09-13 13:31 +0100
              Re: JNI and GetFieldID "Borneq" <borneq@antyspam.hidden.pl> - 2013-09-14 18:50 +0200
              Re: JNI and GetFieldID "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> - 2013-09-19 15:02 +0100

csiph-web