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 i开发者_如何学Pythonf this is particularly stable...?
Is there anything I can do here...?
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().
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.
Another way is getting its address and set one pointer to it with GetDirectBufferAddress method. You can find more information below link:
double * cArr = (double *)((char *)env->GetDirectBufferAddress(inpObject));
GetDirectBufferAddress example for a complex object
精彩评论