2013-05-09 8 views
6

Oppure devo avere una funzione helper JNI che chiama env-> NewDirectByteBuffer (buffer, size)?C'è un modo per creare un ByteBuffer diretto da un puntatore esclusivamente in Java?

+1

Hai guardato sun.misc.unsafe? Ti permette di interagire direttamente con la memoria. – assylias

+0

Ho dato un'occhiata e non ho visto un modo per creare un buffer di byte diretto con sun.misc.unsafe. Ho trovato un modo per creare un DirectByteBuffer ed è attraverso la riflessione. Utilizzare java.lang.Class.getDeclaredConstructor per creare un oggetto Constructor, setAccessable su true e chiamare newInstance con i parametri appropriati. Piccolo janky ma non devi scrivere alcun codice JNI. –

risposta

15

Quello che faccio è creare un normale DirectByteBuffer e cambiarne l'indirizzo.

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); 

Da questo punto è possibile accedere al ByteBuffer riferimento all'indirizzo sottostante. Ho fatto questo per accedere alla memoria su adattatori di rete per la copia zero e ha funzionato bene.

È possibile creare direttamente un DirectByteBuffer per l'indirizzo, ma questo è più oscuro.


Un'alternativa è quella di utilizzare non sicuri (questo funziona solo su OpenJDK/Hotspot JVM e in ordine di byte nativo)

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

Ottima risposta, tuttavia ho dovuto lavorarci sopra per farlo funzionare, in particolare Field address = Buffer.class.getDeclaredField ("address"). – Erik

+0

@Erik grazie per la correzione. –

+0

Quindi ecco un seguito alla domanda originale poiché stai ancora prestando attenzione. Qual è il modo migliore per ripulire la memoria collegata al ByteBuffer in questo modo? Il ByteBuffer completerà l'indirizzo gratuito o il chiamante dovrebbe intervenire e ripulire l'allocazione? Ai fini di questa domanda, supponiamo di aver scritto una libreria JNI con wrapper attorno a malloc e gratis :) Probabilmente merita la sua stessa domanda ora che ci ho pensato di più. – Erik

Problemi correlati