Вопрос

Я нашел множество руководств/вопросов по Stackoverflow, посвященных копированию массивов символов со стороны C/JNI во что-то вроде byte[] в Java, но не наоборот.

Я использую собственную библиотеку C, которая ожидает массив байтов.Я просто хочу получить данные из byte[] в Java, предпочтительно в беззнаковый char[] в 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 byte[] в собственный char* заключается в использовании GetByteArrayRegion вызов.Он делает именно то, что вы хотите:копирует весь или часть массива байтов в собственный буфер.

С использованием GetByteArrayElements/ReleaseByteArrayElements требует двух вызовов вместо одного, и в зависимости от реализации виртуальной машины либо закрепит byte[] в памяти, чтобы предотвратить его перемещение GC, либо вызовет копию, чтобы GC мог свободно перемещать оригинал, не нарушая собственный код.(Это также означает, что JNI_ABORT либо «отменит» изменения, либо оставит их нетронутыми, в зависимости от того, был ли буфер закреплен или скопирован.)

(См. также раздел «Региональные вызовы» на странице Советы по JNI документ.)

А GetArrayLength вызов можно использовать для определения размера byte[].

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top