JNI - Keep native object reference

Discussion in 'Java' started by CD1, Jun 4, 2008.

  1. CD1

    CD1 Guest

    Hi!

    I'm using JNI to wrap a C++ library, and I need to create a native
    object (in C++), and keep this reference in my Java objects for
    further access.

    For example, let's imagine a binary tree, implemented in C++, and I
    want to draw it in a GUI component using Java (what I'm doing is a
    little more complicated than that, but this scenario will do it). So,
    I create a Java class equivalent to the native binary tree, with the
    same methods, and this class is called "JBinaryTree". Suppose I have
    this native method:

    public static native JBinaryTree createBinaryTree();

    and the native implementation would be:

    bintree *tree = new binary_tree();
    return convert_to_jobject(tree);

    The "convert_to_jobject" method can't just copy everything in the tree
    to my Java object, because [suppose] the tree is very large. So, what
    I'm doing right now is creating a private field, in the JBinaryTree
    class:

    private long pointer;

    to hold the pointer of the native C++ object. The "convert_to_jobject"
    function creates a JBinaryTree object and sets the "pointer" field
    with the address of the object:

    env->SetLongField(object, longfid, tree); // tree is a "bintree *"

    The JBinaryTree class doesn't hold actually nothing, only this
    address. In the following JNI calls, I read this "pointer" field, cast
    it to "bintree *" and use the native object normally.

    In some examples I tried, it worked, some others it didn't. But my
    question is if this approach is the most appropriate to this problem,
    or if there's a better way to "bind" a Java object to a C++ object.

    Thanks in advance!
     
    CD1, Jun 4, 2008
    #1
    1. Advertising

  2. CD1

    Arne Vajhøj Guest

    CD1 wrote:
    > I'm using JNI to wrap a C++ library, and I need to create a native
    > object (in C++), and keep this reference in my Java objects for
    > further access.


    > I'm doing right now is creating a private field, in the JBinaryTree
    > class:
    >
    > private long pointer;
    >
    > to hold the pointer of the native C++ object. The "convert_to_jobject"
    > function creates a JBinaryTree object and sets the "pointer" field
    > with the address of the object:
    >
    > env->SetLongField(object, longfid, tree); // tree is a "bintree *"
    >
    > The JBinaryTree class doesn't hold actually nothing, only this
    > address. In the following JNI calls, I read this "pointer" field, cast
    > it to "bintree *" and use the native object normally.
    >
    > In some examples I tried, it worked, some others it didn't. But my
    > question is if this approach is the most appropriate to this problem,
    > or if there's a better way to "bind" a Java object to a C++ object.


    Unless you want to make your JNI code non-thread-safe by having
    a global variable in that, then I think your way is the only way.

    Arne
     
    Arne Vajhøj, Jun 5, 2008
    #2
    1. Advertising

  3. On Wed, 4 Jun 2008 12:46:05 -0700 (PDT), CD1 wrote:
    > I'm using JNI to wrap a C++ library, and I need to create a native
    > object (in C++), and keep this reference in my Java objects for
    > further access.


    [...]

    > The JBinaryTree class doesn't hold actually nothing, only this
    > address. In the following JNI calls, I read this "pointer" field,
    > cast it to "bintree *" and use the native object normally.
    >
    > In some examples I tried, it worked, some others it didn't. But my
    > question is if this approach is the most appropriate to this
    > problem, or if there's a better way to "bind" a Java object to a C++
    > object.


    Can you clarify "some worked, others didn't"?

    I usually recommend the approach you've chosen. It's simple and it
    works, even if there is always a (small) risk when you need an
    explicit typecast in the native code.

    Rob Gordon recommends using a suitable native collection to store the
    C++ objects, and then storing an index or key in Java. It keeps the
    Java and native objects more cleanly separated at the cost of some
    added complexity.

    YMMV, but it really depends on your specific needs.

    /gordon

    --
     
    Gordon Beaton, Jun 5, 2008
    #3
    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. Abhishek Singh

    JVM crashes: Native method, JNI

    Abhishek Singh, Jul 23, 2003, in forum: Java
    Replies:
    2
    Views:
    818
    Nigel Wade
    Jul 23, 2003
  2. Cengiz
    Replies:
    0
    Views:
    367
    Cengiz
    Jul 25, 2003
  3. Cengiz
    Replies:
    2
    Views:
    629
    Joseph Millar
    Jul 26, 2003
  4. Replies:
    4
    Views:
    3,206
  5. bgabrhelik
    Replies:
    0
    Views:
    897
    bgabrhelik
    Sep 29, 2009
Loading...

Share This Page