Transfering callback function to jni

Discussion in 'Java' started by John Smith, Jul 26, 2005.

  1. John Smith

    John Smith Guest

    Hi everyone,

    Lets say you have a jni function which accepts a callback function.
    This function should be set from within java and called if a failure happens
    in the jni code.

    The only examples I've seen of java callbacks are where the java function is
    already known and hardcoded in the jni code. However assume you have a java
    class which calls this jni function you want to be able to create multiple
    objects of this class pointing to each their different function.

    In other words how can I make a java function into a jni function pointer
    and transfer it to the jni code. In .NET this is quite easy by using
    delegates.

    Is it possible in java too or do you need to hardcode the function name
    inside jni?

    Thanks in advance.

    -- John
    John Smith, Jul 26, 2005
    #1
    1. Advertising

  2. John Smith

    jan V Guest

    > In other words how can I make a java function into a jni function pointer
    > and transfer it to the jni code. In .NET this is quite easy by using
    > delegates.
    >
    > Is it possible in java too or do you need to hardcode the function name
    > inside jni?


    If you take a few steps back, maybe you'll agree that you're trying to solve
    a messy architectural problem. Instead of finding a solution for your stated
    problem, maybe you should re-architect the Java-JNI-C interface so that
    you/it obey the KISS principle. E.g. break the C code into more primitive
    chunks which are not given the responsibility to call Java when an error
    occurs, but simply include a C routine which tells you whether an error
    occurred or not.

    But before you consider this route, are you 500% sure you need JNI at all?
    jan V, Jul 26, 2005
    #2
    1. Advertising

  3. John Smith

    John Smith Guest

    > If you take a few steps back, maybe you'll agree that you're trying to
    solve
    > a messy architectural problem. Instead of finding a solution for your

    stated
    > problem, maybe you should re-architect the Java-JNI-C interface so that
    > you/it obey the KISS principle. E.g. break the C code into more primitive
    > chunks which are not given the responsibility to call Java when an error
    > occurs, but simply include a C routine which tells you whether an error
    > occurred or not.
    >
    > But before you consider this route, are you 500% sure you need JNI at all?
    >

    Yes I am sure I need JNI.
    Thing is that I have a library already written in C and I want to expose
    this library through a java wrapper. Building functions which signals errors
    is one way to solve it but it's not very efficient though. The calling java
    application needs to poll for the error to happen.
    I don't like the idea of methods which are hardcoded into jni as callbacks.
    This is just messy if you have more java objects of the wrapper class and
    forces it to become a singleton class.

    I understand that looking from a strict java perspective it's not very
    efficient. However in my case it's a matter of java support to my
    application or none at all. Rewriting thousands of lines from C++ into java
    is not an option.

    Thanks in advance.

    -- John
    John Smith, Jul 26, 2005
    #3
  4. John Smith

    Chris Uppal Guest

    John Smith wrote:

    > Is it possible in java too or do you need to hardcode the function name
    > inside jni?


    You either have to hard-code the function name in the JNI code, or tell the JNI
    code somehow what the name of the function is. Overall the former is simpler
    ;-)

    If it bothers you, you can set up a helper class like:

    abstract class Callback
    {
    abstract void doIt();
    }

    And then pass instances of nested and/or inner classes to JNI, e.g:

    class Example
    {
    private void
    theRealHandler(String location)
    {
    // just for example
    System.err.println("Error in Example." + location + "()");
    }

    void
    methodThatUsesJNI()
    {
    Callback callback = new Callback()
    {
    void doIt()
    {

    theRealHander("methodThatUsesJNI");
    }
    };
    callJNI(params, callback);
    }
    }

    If you see what I mean (and if I haven't cocked up the bloody obfuscatory
    anonymous class syntax again).

    The idea is that you define the Callback class once, and use "local" subclasses
    of it everywhere. JNI only needs to know about (and hard-code) the one
    Callback method.

    -- chris
    Chris Uppal, Jul 27, 2005
    #4
  5. John Smith

    A_Wieminer Guest

    >>Is it possible in java too or do you need to hardcode the function name
    >>inside jni?


    > You either have to hard-code the function name in the JNI code, or tell the JNI
    > code somehow what the name of the function is. Overall the former is simpler
    > ;-)
    >
    > If it bothers you, you can set up a helper class like:
    >
    > abstract class Callback
    > {
    > abstract void doIt();
    > }
    >
    > And then pass instances of nested and/or inner classes to JNI, e.g:
    >
    > class Example
    > {
    > private void
    > theRealHandler(String location)
    > {
    > // just for example
    > System.err.println("Error in Example." + location + "()");
    > }
    >
    > void
    > methodThatUsesJNI()
    > {
    > Callback callback = new Callback()
    > {
    > void doIt()
    > {
    >
    > theRealHander("methodThatUsesJNI");
    > }
    > };
    > callJNI(params, callback);
    > }
    > }
    >
    > If you see what I mean (and if I haven't cocked up the bloody obfuscatory
    > anonymous class syntax again).
    >
    > The idea is that you define the Callback class once, and use "local" subclasses
    > of it everywhere. JNI only needs to know about (and hard-code) the one
    > Callback method.


    Nice and simple abstract callback layer. However, I have always wondered
    whether its safe to call java method from _any_ native thread. Virtual
    machine does not bother the origin thread it is just us to maintain a
    thread safety code when doing callbacks from native side?
    A_Wieminer, Jul 27, 2005
    #5
  6. John Smith

    Chris Uppal Guest

    A_Wieminer wrote:

    > However, I have always wondered
    > whether its safe to call java method from _any_ native thread. Virtual
    > machine does not bother the origin thread it is just us to maintain a
    > thread safety code when doing callbacks from native side?


    I'm not sure that I have understood your question properly. If the following
    doesn't answer your question then please ask again.

    There are two parts to this.

    The first part is that there are definite rules about which threads are allowed
    to call back from native code into Java. If thread is executing native code
    because that code has been called from Java, then it's OK for it to call back
    into Java (on the same thread). If a thread is the one that originally created
    the JVM, then it can call into Java whenever it wants. Otherwise, as I
    understand it (I've never had to use this so I may be wrong), a thread can only
    call Java code if it has registered itself with the JVM by using the JNI
    AttachCurrentThread() function (or similar). Basically you can only call Java
    code from native threads that the JVM "knows" about. A related problem for JNI
    programmers, is that the references to Java objects that Java provides when it
    invokes JNI code, are only valid on that thread. If the programmer wants to
    store a reference to the object for use on another thread, then s/he has to
    convert the reference to a so-called "global" reference (and remember to
    release it later). So, for instance, the Callback object in my example
    couldn't just be stored or passed from thread to thread in the OP's JNI code --
    if he wanted to do that, then he'd have to code for it specially, following the
    JNI rules.

    The second part is that -- providing the above rules are followed -- the
    callback can be invoked from any thread. In this case the picture is just the
    same as if the callback had been invoked from Java code running in a different
    (or potentially different) Java Thread. If that possibility is allowed by your
    application design (it may not be), then you have to code for it by using
    synchronized methods and blocks in the usual way. (It is also possible to
    acquire/release the locks associated with any object directly from JNI, but I'd
    think that would usually be a very bad idea -- and a lot of extra effort too.)

    -- chris
    Chris Uppal, Jul 27, 2005
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mic

    JNI callback and jar

    Mic, Feb 12, 2004, in forum: Java
    Replies:
    1
    Views:
    504
    Gordon Beaton
    Feb 13, 2004
  2. Storm
    Replies:
    2
    Views:
    901
    Storm
    Oct 16, 2004
  3. Replies:
    3
    Views:
    462
  4. Homer

    JNI & CallBack: Please help

    Homer, Oct 31, 2005, in forum: Java
    Replies:
    8
    Views:
    772
    Homer
    Nov 2, 2005
  5. Homer

    CallBack JNI help

    Homer, Nov 15, 2005, in forum: Java
    Replies:
    11
    Views:
    11,764
    Gordon Beaton
    Nov 17, 2005
Loading...

Share This Page