私は1つの方法を知っている-使用してmemcpy
C ++側で:
C ++方法:
void CopyData(void* buffer, int size)
{
memcpy(buffer, source, size);
}
国鉄マッピング:
void CopyData(@Pinned @Out ByteBuffer byteBuffer, @Pinned @In int size);
Java呼び出し:
ByteBuffer buffer = ByteBuffer.allocateDirect(size);
adapter.CopyData(buffer, size);
しかし、私はネイティブコードは、データをコピーし、だけコピーするメモリへのポインタを返していない場合を扱うしたいと思います:
C ++方法:
void* GetData1()
{
return source;
}
// or
struct Data
{
void* data;
};
void* GetData2(Data* outData)
{
outData->data = source;
}
私はにデータをコピーできるようにするには国鉄のマッピングを作成する方法を知っていますHeapByteBuffer
:
Pointer GetData1();
// or
void GetData2(@Pinned @Out Data outData);
final class Data extends Struct {
public final Struct.Pointer data;
public DecodeResult(Runtime runtime) {
super(runtime);
data = new Struct.Pointer();
}
}
Java呼び出し:
ByteBuffer buffer = ByteBuffer.allocate(size);
Pointer dataPtr = adapter.GetData1();
dataPtr.get(0, buffer.array(), 0, buffer.array().length);
// or
ByteBuffer buffer = ByteBuffer.allocate(size);
Data outData = new Data(runtime);
adapter.GetData2(outData);
Pointer dataPtr = outData.data.get();
dataPtr.get(0, buffer.array(), 0, buffer.array().length);
しかし、私はにメモリをコピーする方法は見つかっていないDirectByteBuffer
の代わりにHeapByteBuffer
。上記のコードスニペットは動作しないDirectByteBuffer
ので、buffer.array()
それはネイティブのメモリ領域によって支えられたように、このようなバッファのヌルです。
助けてください。
私はに国鉄ネイティブメモリのコピーを実行するには、いくつかの方法を発見しましたDirectByteBuffer
。彼らは、効率が異なります。現在、私は、私はそれが最善か、国鉄の作者が意図しているかどうかわからない、以下のaproachを使用します。
ByteBuffer buffer = ByteBuffer.allocateDirect(size);
Pointer dataPtr = adapter.GetData1();
long destAddress = ((DirectBuffer)buffer).address();
Pointer destPtr = AsmRuntime.pointerValue(destAddress, runtime);
assert dataPtr.isDirect() && destPtr.isDirect();
dataPtr.transferTo(0, destPtr, 0, size);
若しくは
ByteBuffer buffer = ByteBuffer.allocateDirect(size);
Data outData = new Data(runtime);
adapter.GetData2(outData);
Pointer dataPtr = outData.data.get();
long destAddress = ((DirectBuffer)buffer).address();
Pointer destPtr = AsmRuntime.pointerValue(destAddress, runtime);
assert dataPtr.isDirect() && destPtr.isDirect();
dataPtr.transferTo(0, destPtr, 0, size);
上記のアサート句が満たされていることが重要です。これは、ポインタがあることを保証jnr.ffi.provider.jffi.DirectMemoryIO
インスタンス、および効率的なmemcpy
方法は、(のチェックの実装をコピーするために使用されますDirectMemoryIO.transferTo()
)。
代替はラップすることですDirectByteBuffer
以下の方法を使用しました:
Pointer destPtr = Pointer.wrap(runtime, destAddress);
若しくは
Pointer destPtr = Pointer.wrap(runtime, destAddress, size);
しかし番号:
ポインタdestPtr = Pointer.wrap(ランタイム、バッファ);
第一および第二のポインタがが付いていDirectMemoryIO
たが、第三のポインタによってバックアップされByteBufferMemoryIO
、それが遅いバイト単位のコピーを含みます。
1つの欠点は、ということであるDirectMemoryIO
インスタンスがかなりヘビー級です。それはとても国鉄の呼び出しの多くの場合には、すべて、JVMのヒープ上の32バイトを割り当てDirectMemoryIO
インスタンスは、メモリの大部分を消費します。