有没有办法通过JNI直接指向Java数组?

时间:2011-09-26 15:54:03

标签: java c++ java-native-interface

我需要通过JNI获取一个包含Java数组直接内存地址的指针,而不需要调用某种复制(即直接访问)。

GetArrayElements返回指向复制数组的指针 - 我需要能够直接从本机层修改Java层上的int []。

jintArray转换为int*会成功返回内存地址,但我不确定这是否特别稳定......?

我能在这做什么......?

3 个答案:

答案 0 :(得分:5)

您可以使用直接内存的IntBuffer(具有本机字节顺序)。在JNI中,您可以将地址用作指针。在Java中,您必须使用get()和put()。

答案 1 :(得分:3)

也许。您可以调用的方法可能会直接指向Java内存,但这取决于JVM的功能。

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

  

JNI支持一系列Get / ReleaseArrayElements函数   (包括,例如,Get / ReleaseIntArrayElements)允许   本机代码,用于获取指向基元元素的直接指针   阵列。因为底层垃圾收集器可能不支持   固定,虚拟机可能会返回指向副本的指针   原始原始数组。

请注意,您需要在完成时释放指针。

修改

在JDK 1.3中,添加了函数Get/ReleasePrimtiveArrayCritical()以获取直接指针,即使JVM不支持固定。

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

但是,您应该尽快释放指针,并且您与JVM的交互存在限制。

另一种方法是,如果您与大型数组进行频繁但稀疏的交互,则只能使用GetArrayRegion()函数获取数组中的小区域。

答案 2 :(得分:0)

另一种方法是使用 GetDirectBufferAddress 方法获取其地址并设置一个指针。您可以在以下链接中找到更多信息:

double * cArr = (double *)((char *)env->GetDirectBufferAddress(inpObject));

GetDirectBufferAddress example for a complex object