JNI GetDirectBufferAddress与ByteBuffer.array()

时间:2016-05-24 13:44:54

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

我必须将c ++代码与java混合使用。 java部分分配 java.nio.ByteBuffer ,c ++部分通过 env-&gt; GetDirectBufferAddress(缓冲区)获取它的地址作为jbyte *并填充数据。< / p>

ByteOrder没问题。可以通过buffer.get()。getLong()等在java中检索数据。

但是,方法buffer.array()失败并且hasArray()返回false。 如果我使用buffer.allocate(size)而不是.allocateDirect(size),那么方法array()效果很好,但是我的c ++代码获得了一个NULL的DirectBufferAddress并失败了。

我的问题:如何最好地结合这两个世界,最少复制数据? 或者,如何最简单地用本机c ++数据填充java byte []?

1 个答案:

答案 0 :(得分:4)

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

就程序员而言,我们必须使用DirectByteBuffer来实现从C的最快,无副本访问,但是从Java访问DirectByteBuffer可能会非常慢,而且缺乏 byte [] <的灵活性/ strong>即可。基于数组的ByteBuffer对C库没有任何优势,但它在Java方面可能更有效。

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