Pergunta

Eu encontrei muitos tutoriais / perguntas sobre Stackoverflow que lidam com a cópia de matrizes de caracteres do lado C / JNI em algo como um byte [] em Java, mas não o contrário.

Eu estou usando uma biblioteca nativa C que espera um array de bytes. I simplesmente deseja obter dados a partir de um byte [] em Java, preferencialmente em um unsigned char [] em C.

Para encurtar a história: Qual é a melhor maneira de copiar dados de um jBytearray em JNI? Existe alguma maneira de detectar o seu tamanho?

Foi útil?

Solução

Aqui está um exemplo de trabalho eu só levantou do meu AS / 400 biblioteca JNI para resolver um ponteiro user-fila nativa para testar a existência da fila - ele copia a biblioteca fila e nome de um array de bytes Java (já traduzido para o CCSID do trabalho) em código nativo e usa-lo. Tome nota das chamadas de função de liberação; estas podem ser alterados para copiar a matriz nativa conteúdo de volta para o matrizes de bytes Java para mover dados para o outro lado:

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; }                                                                                           
    }                                                                                                                       

Outras dicas

A melhor maneira de copiar um byte Java [] para um char* nativa é usar a chamada GetByteArrayRegion. Ele faz exatamente o que você quer:. Copia todos ou parte de uma matriz de bytes em um buffer nativo

Usando GetByteArrayElements / ReleaseByteArrayElements requer duas chamadas em vez de um, e dependendo de implementação da VM será ou fixar o byte [] na memória para evitar que o GC de movê-lo, ou fazer uma cópia para que o GC pode mover-se livremente o original sem interromper o código nativo. (Isto também significa que JNI_ABORT vão quer "desfazer" mudanças ou deixá-los intactos, dependendo se o tampão foi preso ou copiado.)

(Veja também a "Região chamadas" do JNI Dicas documento.)

A chamada GetArrayLength pode ser usado para determinar o tamanho do byte[].

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top