Kopieren eines Byte-Puffer mit JNI
-
19-09-2019 - |
Frage
Ich habe viele Tutorials / Fragen auf Stackoverflow, die sich mit dem Kopieren char-Arrays von C / JNI Seite in so etwas wie ein byte [] in Java, aber nicht umgekehrt gefunden.
Ich verwende eine native C-Bibliothek, die einen Byte-Array erwartet. Ich mag einfach Daten erhalten, aus einem byte [] in Java, in vorzugsweise ein unsigned char [] in C.
Lange Rede kurzer Sinn: Was ist der beste Weg, um Daten von einem jBytearray in JNI zu kopieren? Gibt es eine Möglichkeit seiner Größe zu erkennen?
Lösung
Hier ist ein funktionierendes Beispiel ich gerade von meiner AS / 400 JNI-Bibliothek hob einen native Benutzer-Warteschlangenzeiger zu beheben, um die Existenz der Warteschlange zu testen - es kopiert die Warteschlange Bibliothek und Namen von einem Array Java Byte (bereits Aufgabe des CCSID übersetzt) in nativen Code und verwendet es. Beachten Sie die Freigabefunktion Anrufe;
: diese können die native Array-Inhalt zurück in den Java-Byte-Arrays zu bewegen Daten in die andere Richtung zu kopieren geändert werdenJNIEXPORT 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; }
}
Andere Tipps
Der beste Weg, einen Java-byte [] zu einem nativen char*
zu kopieren, ist den GetByteArrayRegion
Anruf zu nutzen. Es tut genau, was Sie wollen. Kopiert alle oder einen Teil eines Arrays von Bytes, die in einem nativen Puffer
Mit GetByteArrayElements
/ ReleaseByteArrayElements
erfordert zwei Anrufe statt einen, und in Abhängigkeit von der Umsetzung der VM wird entweder die Byte-Pin [] im Speicher den GC bewegt, es zu verhindern, oder eine Kopie verursachen, so dass der GC frei das Original bewegen kann, ohne Störung der nativen Code. (Dies bedeutet auch, dass JNI_ABORT
wird entweder „Undo“ Änderungen oder sie intakt lassen, je nachdem, ob der Puffer gepinnt wurde oder kopiert.)
(Siehe auch die "Region Calls" der JNI Tipps Dokument.)
Der GetArrayLength
Aufruf verwendet werden kann, um die Größe des byte[]
zu bestimmen.