Copiare un buffer di byte con JNI
-
19-09-2019 - |
Domanda
Ho trovato un sacco di tutorial / domande su StackOverflow che si occupano di copiare gli array char dal lato C / JNI in qualcosa come un byte [] in Java, ma non il contrario.
Io sto usando una libreria nativa C, che si aspetta un array di byte. Voglio semplicemente per ottenere i dati da un byte [] in Java, in preferibilmente un unsigned char [] in C.
Per farla breve: Qual è il modo migliore di copiare dati da un jBytearray in JNI? C'è un modo per rilevare la sua dimensione?
Soluzione
Ecco un esempio di lavoro ho appena alzato dalla mia libreria AS / 400 JNI per risolvere un puntatore user-code nativo per verificare l'esistenza della coda - copia il libreria di coda e il nome da un array di byte Java (già tradotto in CCSID del lavoro) in codice nativo e lo utilizza. Prendete nota delle chiamate di funzione di rilascio; questi possono essere modificati per copiare il contenuto di array nativo di nuovo nelle matrici di byte Java per spostare i dati da un'altra parte:
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; }
}
Altri suggerimenti
Il modo migliore per copiare un Java byte [] per un char*
nativo è quello di utilizzare la chiamata GetByteArrayRegion
. Fa esattamente quello che vuoi:. Copie in tutto o in parte di un array di byte in un buffer nativo
Uso GetByteArrayElements
/ ReleaseByteArrayElements
richiede due chiamate invece di uno, ea seconda implementazione del VM si pin il byte [] in memoria per impedire il GC da spostarlo, o causare una copia in modo GC possa muoversi liberamente l'originale senza interrompendo il codice nativo. (Questo significa anche che JNI_ABORT
sarà o "annullare" modifiche o lasciarli intatti, a seconda se il buffer è stato bloccato o copiato.)
(Si veda anche la sezione "Chiamate Regione" della JNI Consigli documento.)
La chiamata GetArrayLength
può essere utilizzato per determinare la dimensione del byte[]
.