2013-05-09 12 views
6

または、env-> NewDirectByteBuffer(buffer、size)を呼び出すJNIヘルパ関数が必要ですか?ポインタだけからJavaで直接ByteBufferを作成する方法はありますか?

+1

はあなたがsun.misc.unsafeで見たことがありますか?それはあなたが直接メモリと対話することができます。 – assylias

+0

私はsun.misc.unsafeでダイレクトバイトバッファを作成する方法を見ていませんでした。私はDirectByteBufferを作成する方法を見つけましたが、それは反映されています。 java.lang.Class.getDeclaredConstructorを使用してConstructorオブジェクトを作成し、setAccessableをtrueに設定し、適切なパラメータを指定してnewInstanceを呼び出します。リトルジャンクですが、JNIコードを書く必要はありません。 –

答えて

15

通常のDirectByteBufferを作成してそのアドレスを変更します。

Field address = Buffer.class.getDeclaredField("address"); 
address.setAccessible(true); 
Field capacity = Buffer.class.getDeclaredField("capacity"); 
capacity.setAccessible(true); 

ByteBuffer bb = ByteBuffer.allocateDirect(0).order(ByteOrder.nativeOrder()); 
address.setLong(bb, addressYouWantToSet); 
capacity.setInt(bb, theSizeOf); 

この時点から、基になるアドレスを参照するByteBufferにアクセスできます。私はゼロコピーのためのネットワークアダプタ上のメモリにアクセスするためにこれを行い、それは正常に働いた。

直接アドレス用のDirectByteBufferを作成することはできますが、これはあいまいです。


代替は安全でないを使用することです(OpenJDKの/ホットスポットのJVM上のネイティブのバイト順でのみ動作)

Unsafe.getByte(address); 
Unsafe.getShort(address); 
Unsafe.getInt(address); 
Unsafe.getLong(address); 
+0

偉大な答え、しかし、私はそれを動作させるためにいくつかの、特にフィールドアドレス= Buffer.class.getDeclaredField( "アドレス")ハックしなければならなかった。 – Erik

+0

@エリック訂正ありがとうございます。 –

+0

あなたがまだ注意を払っているので、ここに元の質問へのフォローアップがあります。この方法でByteBufferに接続されたメモリをクリーンアップする最善の方法は何ですか? ByteBufferは空きアドレスを確定しますか、または発信者が割り込んで割り振りをクリーンアップする必要がありますか?この質問の目的のために、私はmallocの周りにラッパーを入れたJNIライブラリを書いたと仮定します:)おそらく私はもっとそれについて考えていたので、それはおそらくそれ自身の問題です。 – Erik

関連する問題