Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to get a direct pointer to a Java array via JNI?

I need to get a pointer containing the direct memory address of a Java array, via JNI, without invoking some sort of copying (ie direct access).

GetArrayElements returns a pointer to a copied array - I need to be able to modify an int[] on the Java layer directly from a the native layer.

Casting from a jintArray to an int* returns the memory address successfully, but I'm not sure if this is particularly stable...?

Is there anything I can do here...?

like image 953
user965369 Avatar asked Jan 19 '23 15:01

user965369


2 Answers

You can use an IntBuffer using direct memory (with native byte order). In JNI you can use the address as a pointer. In Java you have to use the get() and put().

like image 140
Peter Lawrey Avatar answered Jan 21 '23 04:01

Peter Lawrey


Maybe. There are methods you can call that might give you a direct pointer to the Java memory, but that depends on the capabilities of the JVM.

From http://java.sun.com/docs/books/jni/html/objtypes.html#4099 :

The JNI supports a family of Get/ReleaseArrayElements functions (including, for example, Get/ReleaseIntArrayElements) that allow the native code to obtain a direct pointer to the elements of primitive arrays. Because the underlying garbage collector may not support pinning, the virtual machine may return a pointer to a copy of the original primitive array.

Note that you need to release the pointer when you're through with it.

EDIT:

In JDK 1.3, the functions Get/ReleasePrimtiveArrayCritical() were added to obtain a direct pointer even if the JVM does not support pinning.

"These restrictions make it more likely that the native code will 
obtain an uncopied version of the array, even if the VM does not 
support pinning. For example, a VM may temporarily disable garbage 
collection when the native code is holding a pointer to an 
array obtained via GetPrimitiveArrayCritical."

However, you're expected to release the pointer as soon as possible, and there are restrictions on your interactions with the JVM.

An alternative, if you have frequent but sparse interactions with a large array, is to get only small regions in the array, with GetArrayRegion() functions.

like image 28
Andy Thomas Avatar answered Jan 21 '23 05:01

Andy Thomas