2011-12-15 10 views
5

Tengo un proyecto de Android (dirigido a Android 1.6 y superior) que incluye código nativo escrito en C/C++, al que se accede a través de NDK. Me pregunto cuál es la forma más eficiente de pasar una matriz de bytes desde Java a través de NDK a mi capa de pegamento JNI. Mi preocupación es si NDK para Android copiará o no la matriz de bytes, o simplemente me dará una referencia directa. Necesito acceso de solo lectura a los bytes en el nivel C++, por lo que cualquier copia detrás de escena sería una pérdida de tiempo desde mi perspectiva.Android: forma más eficiente de pasar algunos bytes de solo lectura a C++ nativo

Es fácil encontrar información sobre esto en la web, pero no estoy seguro de cuál es la información más pertinente. Ejemplos:

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

Así que ¿alguien sabe cuál es la mejor manera (más eficiente, menos copiado) de hacer esto en la corriente NDK? GetByteArrayRegion? GetByteArrayElements? ¿Algo más?

Respuesta

5

De acuerdo con la documentación, GetDirectBufferAddress le dará la referencia sin copiar la matriz.

Sin embargo, para llamar a esta función necesita asignar un direct buffer con ByteBuffer.allocateDirect() en lugar de una matriz de bytes simple. Tiene una contraparte como explained here:

Un buffer de bytes directa se pueden crear mediante la invocación del método de fábrica allocateDirect de esta clase. Los almacenamientos intermedios devueltos por este método normalmente tienen costos de asignación y desasignación algo mayores que memorias intermedias no directas. El contenido de los búferes directos puede residir fuera del del montón normal recogido de basura, por lo que su impacto en la memoria de una aplicación puede no ser obvio. Es , por lo tanto, se recomienda que los búferes directos se asignen principalmente para búferes grandes y de larga duración que están sujetos a las operaciones de E/S nativas del sistema subyacente . En general, es mejor asignar buffers directos solo cuando produzcan una ganancia medible en el rendimiento del programa .

+0

¿Existe alguna API eficiente similar para hacer lo contrario? - pasar 'unsigned char *' desde la capa nativa a la capa Java como 'byte []' o 'byteBuffer' –

+0

Ambos ByteBuffer directo y byte [] se pueden usar para lectura/escritura desde/hacia el lado nativo. Puede usar la función de memoria de C para leer/copiar, una vez que haya llamado env-> GetDirectBufferAddress (buffer) o env-> Get ArrayElements (array, ...). PERO Direct ByteBuffer es mucho más rápido, no reproduce copias, es más seguro, etc., etc. –

Cuestiones relacionadas