DirectByteBufferにネイティブメモリをコピーする方法

sgnsajgon:

私は1つの方法を知っている-使用してmemcpyC ++側で:

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()それはネイティブのメモリ領域によって支えられたように、このようなバッファのヌルです。

助けてください。

sgnsajgon:

私はに国鉄ネイティブメモリのコピーを実行するには、いくつかの方法を発見しました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インスタンスは、メモリの大部分を消費します。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=180678&siteId=1