collection of jMethodID objects

V

Vikas

Hi
I want to create a struct in Java that when passed to a native/JNI C
function gets converted to a bunch of jMethodIDs.

For example, in my C code I need my structure to be like this:

struct java_callbacks {
jMethodID callback1;
jMethodID callback2;
jMethodID callback3;
};

But I want to create an object of this type in my Java class. For
example,
public class my_java_class
{
private JavaCallbacks callback_struct;
<functions>;
}

Where JavaCallbacks is the equivalent class/struct of the C struct
java_callbacks.

The reason I have to do this, is that I want the callback_struct to be
destroyed/garbage collected with the Java Class object and not have to
do it manually in the Native interface.

Could anyone enlighten me as to how I could do this easily ?

In C#, I was able to do it fairly easily by defining "public delegate"
functions and then making them part of a "struct" in C# and making an
object of that struct in the C# class. Then I could directly access
the members of the struct in C.
But I am not a Java programmer as such, and am having difficulty in
getting it to work in this way.

Thanks and regards,

Vikas
 
C

Chris Uppal

Vikas said:
The reason I have to do this, is that I want the callback_struct to be
destroyed/garbage collected with the Java Class object and not have to
do it manually in the Native interface.

There are two ways to do this that I know of.

One way is to keep the data in Java space only, probably as a bunch of longs
associated in some way with the class -- a static long[] array might be
simplest. And then, whenever you need access to it from JNI code, you either
ask Java for it (read the static field from JNI) or you design the API so that
the array is always passed as a parameter to any JNI function which will need
it.

The other way is to use some form of finalisation -- either an explicit
finalize() method on a custom class, or a reference queue (see
java.lang.ref.WeakReference or java.lang.ref.PhantomReference). You keep the
data in C-space, but keep a "handle" to it in Java space -- the handle might be
a long representing the data's address, or it might be an index into some
array. Or it might even be empty (zero bits) if there can only ever be one
such datastructure (so you don't need extra data to identify /which/
datastructure it is). Anyway, you use finalisation to detect when the Java
object which /hold/ that handle is GCed, and then invoke a native method which
will release the data in C-space.

But it's not clear that you need to do either. Unless you are using
classloaders in some moderately sophisticated way (or you code runs in some
container which uses classloaders in that way), the class will not be GCed
during the application's lifetime. So there may be little point in cleaning up
the data in C-space at all.

Another point: if you are creating this structure /only/ as a performance
optimisation (to avoid unnecessary calls to GetMethodId()) then you should
probably check what the actual performance is before creating a lot of extra
complication. I haven't measured it recently, but don't I think that
GetMethodId() is as slow as some JNI tutorials seem to suggest.

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

No members online now.

Forum statistics

Threads
474,430
Messages
2,571,676
Members
48,796
Latest member
Greg L.

Latest Threads

Top