2016-05-24 14 views
2

javaとC++コードを混在させる必要があります。 java部分はjava.nio.ByteBufferを割り当て、C++部分はenv-> GetDirectBufferAddress(バッファ)をjbyte *としてアドレスを取得し、データを埋め込みます。JNI GetDirectBufferAddressとByteBuffer.array()

ByteOrderは問題ありません。データをJavaでbuffer.get().getLong()などで取得できます。

ただし、buffer.array()メソッドは失敗し、hasArray()はfalseを返します。 .allocateDirect(size)の代わりにbuffer.allocate(size)を使用すると、array()メソッドは正常に動作しますが、C++コードはNULLのDirectBufferAddressを取得して失敗します。

私の質問:データのコピーを最小限に抑えながら、両方の世界をどのように組み合わせるとよいでしょうか? または、Javaバイト[]をネイティブのC++データで簡単に埋める方法は?

答えて

3

ByteBufferクラスは本当に混乱しています。実際には、2つのまったく異なるクラスの1つ、DirectByteBufferとArrayByteBufferのラッパーです。なぜこれが起こったのかは、歴史家の問題です。 JavaからDirectByteBufferへ

限り、プログラマが懸念しているとして、我々は最速を達成するためにDirectByteBufferを使用する必要があり、ノーコピーCからのアクセスが、アクセスは非常に遅くなることがあり、それはバイト[]の柔軟性を欠いています。配列ベースのByteBufferはCライブラリにとって利点はありませんが、Java側でははるかに効率的です。

一方、JNIはバイト[]を含むプリミティブ配列へのアクセスを提供します。多くの場合、そのようなアクセスにはコピーは含まれません。特にGetPrimitiveArrayCritical()を使用する場合はそうです。まあ、保証はありません。しかし、現代的なハードウェア上に最新の最適化されたJVMを物理RAMと仮想RAMを無制限に使用すると、C/C++とJavaの両方から効率的にアクセスできる可能性が非常に高くなります。

+1

良いヒントByteBufferの範囲を超えて注意してください。 既存のC++コードに触れることを躊躇し、 "research" GetPrimitiveArrayCritical()は言い訳ではありません;) – datafiddler