Я нашел много учебных руководств / вопросы на Stackoverflow, которые имеют дело с копированием массивов символов со стороны C/JNI во что-то как байт [] в Java, но не наоборот.
Я пользуюсь собственной библиотекой C, которая ожидает массив байтов. Я просто хочу получить данные из байта [] в Java в предпочтительно неподписанный символ [] в C.
Длинная короткая история: Каков лучший способ скопировать данные из jBytearray в JNI? Там какой-либо путь состоит в том, чтобы обнаружить, это - размер?
Вот рабочий пример, который я только что взял из своей библиотеки JNI AS / 400, чтобы разрешить собственный указатель пользовательской очереди для проверки существования очереди - он копирует библиотеку очереди и имя из байтового массива Java (уже переведенного в CCSID задания) в собственный код и использует его. Обратите внимание на вызовы функций выпуска; их можно изменить, чтобы скопировать содержимое собственного массива обратно в байтовые массивы Java, чтобы переместить данные другим способом:
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; }
}
Лучший способ скопировать байт[] из Java в нативный char*
- использовать вызов GetByteArrayRegion
. Он делает именно то, что вы хотите: копирует весь массив байтов или его часть в родной буфер.
Использование GetByteArrayElements
/ReleaseByteArrayElements
требует двух вызовов вместо одного, и в зависимости от реализации виртуальной машины будет либо фиксировать байт[] в памяти, чтобы GC не мог его переместить, либо вызывать копию, чтобы GC мог свободно перемещать оригинал, не нарушая нативный код. (Это также означает, что JNI_ABORT
либо "отменит" изменения, либо оставит их нетронутыми, в зависимости от того, был ли буфер прижат или скопирован.)
(См. также раздел "Вызовы регионов" документа Советы по JNI.)
Вызов GetArrayLength
можно использовать для определения размера byte[]
.