私は次のことを達成しようとしています:
1) イメージを表す Java 側のバイト配列があります。
2) ネイティブ コードからアクセスできるようにする必要があります。
3) ネイティブ コードは、GraphicsMagick を使用してこの画像をデコードし、resize を呼び出して一連のサムネイルを作成します。また、ベクトルまたは unint8_t 配列のいずれかである画像の知覚ハッシュも計算します。
4) このデータを Java 側に戻すと、別のスレッドがそれを読み取ります。サムネイルは、HTTP 経由で外部ストレージ サービスにアップロードされます。
私の質問は次のとおりです。
1) Java からネイティブ コードにバイトを渡す最も効率的な方法は何ですか? バイト配列としてアクセスできます。ここでは、バイト配列と比較して、バイトバッファーとして渡す (このバイト配列をラップする) ことに特に利点はありません。
2) これらのサムネイルと知覚ハッシュを Java コードに返す最良の方法は何でしょうか? 私はいくつかのオプションを考えました:
(i) Java でバイト バッファを割り当て、それをネイティブ メソッドに渡すことができました。次に、ネイティブ メソッドはそれに書き込み、完了後に制限を設定し、書き込まれたバイト数または成功を示すブール値を返すことができます。次に、バイト バッファーをスライス アンド ダイスして個別のサムネイルと知覚ハッシュを抽出し、サムネイルをアップロードするさまざまなスレッドに渡すことができます。このアプローチの問題は、割り当てるサイズがわからないことです。必要なサイズは、事前にわからない生成されたサムネイルのサイズとサムネイルの数によって異なります (これは事前にわかっています)。
(ii) 必要なサイズがわかれば、ネイティブ コードでバイト バッファーを割り当てることもできます。カスタム パッキング プロトコルに基づいて blob を適切な領域に memcpy し、このバイト バッファーを返すことができました。(i) と (ii) はどちらも、各サムネイルの長さと知覚ハッシュを示す必要があるカスタム パッキング プロトコルのため、複雑に見えます。
(iii) サムネイル用のフィールドを持つ Java クラスを定義します: バイト バッファーの配列と知覚ハッシュ: バイト配列。必要な正確なサイズがわかっている場合は、ネイティブ コードでバイト バッファーを割り当てることができます。次に、GraphicsMagick blob からのバイトを各バイト バッファーの直接アドレスに memcpy できます。Javaコードがバイトバッファの大きさを認識できるように、バイトバッファに書き込まれるバイト数を設定する方法もあると想定しています。バイト バッファーが設定された後、Java オブジェクトを入力して返すことができます。(i) および (ii) と比較して、ここではより多くのバイト バッファーと Java オブジェクトを作成しますが、カスタム プロトコルの複雑さを回避します。(i)、(ii)、(iii) の背景にある理論的根拠 - 私がこれらのサムネイルを使って行う唯一のことは、それらをアップロードすることだとすると、
(iv) サムネイル用の (バイト バッファーではなく) バイト配列の配列と、知覚ハッシュ用のバイト配列を持つ Java クラスを定義します。これらの Java 配列をネイティブ コードで作成し、SetByteArrayRegion を使用して GraphicsMagick blob からバイトをコピーします。以前の方法と比較した場合の欠点は、アップロード時にこのバイト配列をヒープから直接バッファーにコピーするときに、Java ランドにさらに別のコピーが存在することです。ここでも、(iii) に対して複雑さの点で何かを節約できるかどうかはわかりません。
どんなアドバイスも素晴らしいでしょう。
編集: @main は興味深い解決策を提案しました。そのオプションをフォローアップするために質問を編集しています。@main が示唆するように DirectBuffer でネイティブ メモリをラップしたい場合、いつネイティブ メモリを安全に解放できるかをどのように知ることができますか?