JNI GetDirectBufferAddress vs. ByteBuffer.array()

JNI GetDirectBufferAddress vs. ByteBuffer.array()

本文关键字:array ByteBuffer GetDirectBufferAddress vs JNI      更新时间:2023-10-16

我必须将c ++代码与java混合在一起。java 部分分配一个 java.nio.ByteBuffer,c++ 部分通过 env->GetDirectBufferAddress(buffer) 作为 jbyte* 获取它的地址并填充数据。

字节顺序是可以的。数据可以通过buffer.get() .getLong()等在java中检索。

但是,方法buffer.array()失败,hasArray()返回false。如果我使用 buffer.allocate(size) 而不是 .allocateDirect(size),则方法array() 运行良好,但我的 c++ 代码获得 NULL 的 DirectBufferAddress 并失败。

我的问题:如何才能最好地结合这两个世界,同时减少数据复制?或者,如何最容易地用原生 c++ 数据填充 java 字节 []?

ByteBuffer 类确实令人困惑。它实际上是两个完全不同的类之一的包装器:DirectByteBuffer 和 ArrayByteBuffer。为什么会这样,是历史学家的问题。

就程序员而言,我们必须使用 DirectByteBuffer 来实现来自 C 的最快、无复制访问,但从 Java 访问 DirectByteBuffer 可能相当慢,并且缺乏 byte[] 的灵活性。基于数组的 ByteBuffer 对 C 库没有优势,但在 Java 端可能效率更高。

另一方面,JNI 确实提供了对基元数组的访问,包括 byte[]。在许多情况下,此类访问不涉及复制,尤其是在您使用 GetPrimitiveArrayCritical() .好吧,没有保证。但是,如果您在具有丰富物理 RAM 和几乎无限虚拟 RAM 的现代硬件上使用现代优化的 JVM,那么您从 C/C++ 和 Java 进行高效访问的机会非常高。