2011-12-15 9 views
5

Ho un progetto Android (destinato a Android 1.6 e versioni successive) che include codice nativo scritto in C/C++, accessibile tramite NDK. Mi chiedo quale sia il modo più efficiente per passare una serie di byte da Java a NDK al mio livello di colla JNI. La mia preoccupazione è che NDK per Android copi o meno la matrice di byte o semplicemente mi dia un riferimento diretto. Ho bisogno di un accesso di sola lettura ai byte al livello C++, quindi qualsiasi copia dietro le quinte sarebbe una perdita di tempo dal mio punto di vista.Android: il modo più efficiente per passare alcuni byte di sola lettura a C++ nativo

È facile trovare informazioni su questo sul web, ma non sono sicuro di quali siano le informazioni più pertinenti. Esempi:

Get the pointer of a Java ByteBuffer though JNI

http://www.milk.com/kodebase/dalvik-docs-mirror/docs/jni-tips.html

http://elliotth.blogspot.com/2007/03/optimizing-jni-array-access.html

Quindi qualcuno sa qual è la migliore (, almeno la copia più efficace) modo per fare questo nella corrente NDK? GetByteArrayRegion? GetByteArrayElements? Qualcos'altro?

risposta

5

Secondo la documentazione, GetDirectBufferAddress fornirà il riferimento senza copiare la matrice.

Tuttavia, per chiamare questa funzione è necessario allocare uno direct buffer con ByteBuffer.allocateDirect() invece di un semplice array di byte. Esso ha una controparte come explained here:

Un buffer di byte diretta possono essere create richiamando il metodo factory allocateDirect di questa classe. I buffer restituiti con questo metodo hanno in genere costi di allocazione e deallocazione leggermente superiori rispetto ai buffer non diretti . Il contenuto dei buffer diretti può risiedere all'esterno dello del normale heap spazzato, e quindi il loro impatto sull'impronta di memoria di un'applicazione potrebbe non essere ovvio. È pertanto che consiglia di allocare i buffer diretti principalmente per i buffer grandi, longevi soggetti alle operazioni di I/O native del sistema sottostante . In generale, è meglio allocare i buffer diretti solo quando danno un guadagno misurabile nel rendimento del programma .

+0

Esiste un API efficiente simile per fare il contrario? - passando 'char unsigned *' dal livello nativo al livello Java come 'byte []' o 'byteBuffer'? –

+0

Sia ByteBuffer diretto che byte [] possono essere utilizzati per la lettura/scrittura da/verso il lato nativo. Puoi usare la funzione memcopy di C per leggere/copiare, dopo aver chiamato env-> GetDirectBufferAddress (buffer) o env-> Get ArrayElements (array, ...). MA ByteBuffer diretto è molto più veloce, non riprodurre copie, è più sicuro, ecc. Ecc –

Problemi correlati