tags:

views:

516

answers:

5

What is the 'correct' way to store a native pointer inside a Java object?

I could treat the pointer as a Java int, if I happen to know that native pointers are <= 32 bits in size, or a Java long if I happen to know that native pointers are <= 64 bits in size. But is there a better or cleaner way to do this?

Edit: Returning a native pointer from a JNI function is exactly what I don't want to do. I would rather return a Java object that represents the native resource. However, the Java object that I return must presumably have a field containing a pointer, which brings me back to the original question.

Or, alternatively, is there some better way for a JNI function to return a reference to a native resource?

+2  A: 

A better way might by to store it in a byte array, since native pointers aren't very Java-ish in the first place. ints and longs are better reserved for storing numeric values.

Avi
+2  A: 

I assume that this is a pointer returned from some JNI code and my advice would be just dont do it :)

Ideally the JNI code should pass you back some sort of logical reference to the resource and not an actual pointer ?

As to your question there is nothing that comes to mind about a cleaner way to store the pointer - if you know what you have then use either the int or long or byte[] as required.

LenW
Could you give an example of a 'logical reference to the resource'? I edited my question to clarify what I meant a bit.
Daniel Cassidy
The logical reference would simply be a number that the jni code returns that is used on subsewuent calls back to the jni to reference something. the jni code can then dereference that via some sort of structure, e.g. an array[ref][pointer]. hth
LenW
That would mean maintaining an array containing pointers to every resource that needs to be referenced from Java. I don't think that's a very good idea...
Daniel Cassidy
It is kind of what the JVM does. I see some advantages in that the Java code does not need to deal with the specifics of the pointers in the JNI code and is protected from them. How many resources are you sharing back to the Java code ? 10000 element array does not seem too large :)
LenW
In practice, probably hardly any. But I just don't like the idea of either imposing some arbitrary cap on object creation or having to write code to resize arrays and so forth, not least because that's one more source of potential bugs.
Daniel Cassidy
A: 

You could look to the way C# handles this with the IntPtr type. By creating your own type for holding pointers, the same type can be used as a 32-bit or 64-bit depending on the system you're on.

ctacke
+3  A: 

IIRC, both java.util.zip and java.nio just use long.

Tom Hawtin - tackline
+1. Use a long, as the Java runtime does itself.
erickson
using an object that wraps a long has overhead: it might double memory consumption as an object shell might occupy at least 8 bytes not to mention the instances of your wrapper type will have to be garbage collected
Gregory Pakosz
+1  A: 

There is no good way. In SWT, this code is used:

int /*long*/ hModule = OS.GetLibraryHandle ();

and there is a tool which converts the code between 32bit and 64bit by moving the comment. Ugly but it works. Things would have been much easier if Sun had added an object "NativePointer" or something like that but they didn't.

Aaron Digulla