JNI - Keep native object reference

C

CD1

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!
 
A

Arne Vajhøj

CD1 said:
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
 
G

Gordon Beaton

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

--
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top