<分区>
我必须将 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 byte[]?
ByteBuffer 类确实令人困惑。它实际上是两个完全不同的类之一的包装器:DirectByteBuffer 和 ArrayByteBuffer。为什么会这样,这是历史学家的问题。
对于程序员而言,我们必须使用 DirectByteBuffer 来实现最快的 C 无复制访问,但是从 Java 访问 DirectByteBuffer 可能会很慢,并且缺乏 byte[]< 的灵 active /强>。基于数组的 ByteBuffer 对于 C 库没有优势,但它在 Java 端可能更高效。
另一方面,JNI 确实提供了对原始数组的访问,包括 byte[]。在许多情况下,此类访问不涉及复制,尤其是当您使用 GetPrimitiveArrayCritical()
时。嗯,没有保证。但是,如果您在具有丰富物理 RAM 和几乎无限虚拟 RAM 的现代硬件上使用经过现代优化的 JVM,那么从 C/C++ 和 Java 进行高效访问的机会就非常高。