Pregunta

He encontrado un montón de tutoriales / preguntas sobre Stackoverflow que tienen que ver con la copia de arrays de char de un lado C / JNI en algo así como un byte [] en Java, pero no al revés.

Estoy utilizando una biblioteca nativa C, que espera una matriz de bytes. Simplemente quiero obtener datos de un byte [] en Java, en preferencia un unsigned char [] en C.

En resúmen: ¿Cuál es la mejor manera de copiar datos de un jbyteArray en JNI? ¿Hay alguna manera de detectar su tamaño?

¿Fue útil?

Solución

Aquí hay un ejemplo de trabajo que sólo se levantan de mi biblioteca de AS / 400 JNI para resolver un puntero de usuario-cola nativa para probar la existencia de la cola - copia la biblioteca cola y el nombre de una matriz de bytes de Java (ya traducido al CCSID del trabajo) en código nativo y lo utiliza. Tomar nota de las llamadas a la función de liberación; estos se pueden cambiar para copiar el contenido de la matriz nativas de nuevo en las matrices de bytes de Java para mover datos a la inversa:

JNIEXPORT jboolean JNICALL Java_com_mycompany_jni400_UserQueue_jniResolve(JNIEnv *jep,jobject thsObj,                
jbyteArray queueLibrary,jbyteArray queueName) {                                                                             
    jbyte            *lib,*nam;                                                                                             
    bool             rtn;                                                                                                   

    thsObj=thsObj;                                                                                                          
    lib=(*jep)->GetByteArrayElements(jep,queueLibrary,0);                                                                   
    nam=(*jep)->GetByteArrayElements(jep,queueName,0);                                                                      
    rtn=(usrq_resolve((byte*)lib,(byte*)nam)!=NULL);                                                                        
    (*jep)->ReleaseByteArrayElements(jep,queueLibrary,lib,JNI_ABORT); /* abort to not copy back contents */                 
    (*jep)->ReleaseByteArrayElements(jep,queueName   ,nam,JNI_ABORT); /* abort to not copy back contents */                 
    if(rtn) { return JNI_TRUE;  }                                                                                           
    else    { return JNI_FALSE; }                                                                                           
    }                                                                                                                       

Otros consejos

La mejor manera de copiar un byte de Java [] a un char* nativa es el uso de la llamada GetByteArrayRegion. Hace exactamente lo que quiere:. Copias totalidad o parte de una matriz de bytes en un búfer nativo

El uso de GetByteArrayElements / ReleaseByteArrayElements requiere dos llamadas en lugar de uno, y dependiendo de la implementación de la máquina virtual o bien fijar el byte [] en la memoria para evitar que el GC se mueva, o causar una copia por lo que el GC se puede mover libremente el original sin interrumpir el código nativo. (Esto también significa que JNI_ABORT o bien "deshacer" los cambios o dejarlos intactos, dependiendo de si el tampón se inmovilizó o copiado.)

(Véase también la sección "Llamadas región" de la JNI href="http://developer.android.com/training/articles/perf-jni.html" rel="noreferrer"> Consejos documento.)

La llamada GetArrayLength se puede utilizar para determinar el tamaño de la byte[].

scroll top