JNI GetDirectBufferAddress 与 ByteBuffer.array()
JNI GetDirectBufferAddress vs. ByteBuffer.array()
我必须将 C++ 代码与 java 混合使用。
java 部分分配一个 java.nio.ByteBuffer 并且 c++ 部分通过 env->GetDirectBufferAddress(buffer) 获取它的地址作为一个 jbyte* 并填充数据。
字节顺序没问题。可以通过 buffer.get() .getLong() 等在 java 中检索数据
然而,方法 buffer.array() 失败并且 hasArray() returns 错误。
如果我使用 buffer.allocate(size) 而不是 .allocateDirect(size) 方法 array() 效果很好,但我的 c++ 代码得到一个 NULL 的 DirectBufferAddress 并失败。
我的问题:我怎样才能最好地将两个世界结合起来,同时最少的数据复制?
或者,如何最简单地用原生 C++ 数据填充 java byte[]?
ByteBuffer class 确实令人困惑。它实际上是两个完全不同的 classes 之一的包装器:DirectByteBuffer 和 ArrayByteBuffer。为什么会这样,这是历史学家的问题。
对于程序员而言,我们必须使用 DirectByteBuffer 来实现最快的 C 无复制访问,但是从 Java 访问 DirectByteBuffer 可能会很慢,并且缺乏 字节[]。基于数组的 ByteBuffer 对 C 库没有优势,但在 Java 方面可能效率更高。
另一方面,JNI 确实提供了对基本数组的访问,包括 byte[]。在许多情况下,此类访问不涉及复制,特别是如果您使用 GetPrimitiveArrayCritical()
。嗯,没有保证。但是,如果您在具有丰富物理 RAM 和几乎无限虚拟 RAM 的现代硬件上使用现代优化的 JVM,那么从 C/C++ 和 Java 进行有效访问的机会非常高。
我必须将 C++ 代码与 java 混合使用。 java 部分分配一个 java.nio.ByteBuffer 并且 c++ 部分通过 env->GetDirectBufferAddress(buffer) 获取它的地址作为一个 jbyte* 并填充数据。
字节顺序没问题。可以通过 buffer.get() .getLong() 等在 java 中检索数据
然而,方法 buffer.array() 失败并且 hasArray() returns 错误。 如果我使用 buffer.allocate(size) 而不是 .allocateDirect(size) 方法 array() 效果很好,但我的 c++ 代码得到一个 NULL 的 DirectBufferAddress 并失败。
我的问题:我怎样才能最好地将两个世界结合起来,同时最少的数据复制? 或者,如何最简单地用原生 C++ 数据填充 java byte[]?
ByteBuffer class 确实令人困惑。它实际上是两个完全不同的 classes 之一的包装器:DirectByteBuffer 和 ArrayByteBuffer。为什么会这样,这是历史学家的问题。
对于程序员而言,我们必须使用 DirectByteBuffer 来实现最快的 C 无复制访问,但是从 Java 访问 DirectByteBuffer 可能会很慢,并且缺乏 字节[]。基于数组的 ByteBuffer 对 C 库没有优势,但在 Java 方面可能效率更高。
另一方面,JNI 确实提供了对基本数组的访问,包括 byte[]。在许多情况下,此类访问不涉及复制,特别是如果您使用 GetPrimitiveArrayCritical()
。嗯,没有保证。但是,如果您在具有丰富物理 RAM 和几乎无限虚拟 RAM 的现代硬件上使用现代优化的 JVM,那么从 C/C++ 和 Java 进行有效访问的机会非常高。