JNI - keeping state in the DLL?

T

Tim Ward

When a Java application makes multiple calls into a DLL via JNI for the same
Java object, what's the conventional idiom for the DLL to store state
relating to the Java object, where there is no reason to expose the DLL's
state information to the Java code (other than via the JNI calls) and where
calls into the DLL relating to the same object will be from different
threads (if that makes a difference)?

(1) Does the DLL keep a map from the passed "jobject" to its private data?
Does that work? - is the passed "jobject" the same every time the DLL is
called in relation to the same Java object (regardless of thread and garbage
collection history)? If you do this how do you know when the Java object has
gone away so as to release the state in the DLL?

(2) Does the DLL store a pointer to its state in, say, an integer member in
the Java object, which the Java code promises not to look at? Again, in this
case how does the DLL know when the Java object has gone away so as to be
able to release the state?

(3) Given that the above two both sound unsatisfactory, how do people really
do it?
 
G

Gordon Beaton

(1) Does the DLL keep a map from the passed "jobject" to its private
data? Does that work? - is the passed "jobject" the same every time
the DLL is called in relation to the same Java object (regardless of
thread and garbage collection history)?

That's one way. I believe you always get the same object pointer for
each object, but I'm not 100% sure.
(2) Does the DLL store a pointer to its state in, say, an integer
member in the Java object, which the Java code promises not to look
at? Again, in this case how does the DLL know when the Java object
has gone away so as to be able to release the state?

That's the mechanism I use. After allocating the state (in a native
method called from the constructor), I return the pointer as a long
and store it in the object. Then I pass the pointer to the native
method on each call. You could also look it up each time, but I find
that tedious.

To reclaim the storage when the object goes away you should make sure
your user disposes the object properly (e.g. by calling close() or
similar method). The alternative is to rely on finalization, IMO a
poorer choice.

I imagine you could map SoftReferences to state objects in the
library, and implement a simple garbage collector that you call at
specific points (e.g. when entering or leaving certain methods).

There is some discussion of this in section 9.5 of the Liang book,
available online at java.sun.com, and in Rob Gordon's JNI book (at
home, so I can't check the reference right now).

/gordon
 
T

Tim Ward

Gordon Beaton said:
That's the mechanism I use. After allocating the state (in a native
method called from the constructor), I return the pointer as a long
and store it in the object. Then I pass the pointer to the native
method on each call. You could also look it up each time, but I find
that tedious.

Yes, that seems to work, thanks. (I'm doing the direct prodding and poking
of the Java member rather than passing it each time.)
 
C

Chris Uppal

Gordon said:
To reclaim the storage when the object goes away you should make sure
your user disposes the object properly (e.g. by calling close() or
similar method). The alternative is to rely on finalization, IMO a
poorer choice.

I don't agree that finalisation is a poor choice here; in fact I would say that
it (or one of the variants) is precisely the right choice -- assuming the
resource that is being reclaimed is only memory (if not then the usual
arguments against finalisation apply).

-- chris
 

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,772
Messages
2,569,593
Members
45,111
Latest member
VetaMcRae
Top