Como retornar vetor de uma função em JNI

Boa tarde galera…

to quebrando a cabeça aqui, mas acho que não deve ser tão difícil, alguem pode dar uma forcinha, por favor!!!
quero retornar um vetor de inteiros para a aplicação java, minha função em C++ tá assim

JNIEXPORT jintArray JNICALL Java_DllFuntions_DllFuntions_ReadData(JNIEnv * env, jobject) { int countReadData=0;// contador para o vetor int buffer[LEN_BUFFER];// vetor que pretendo retornar if(ReadFile( hCom, BufferRecebe, LEN_BUFFER, &BytesLidos, NULL) != 0 ) { if(BytesLidos>0){ BufferRecebe[BytesLidos]='\0';// finaliza o vetor printf("Bytes lidos: %d\n",BytesLidos); for(countReadData=0;countReadData<BytesLidos;countReadData++){ buffer[countReadData]=BufferRecebe[countReadData];// armazena os dados no vetor printf("Dados lidos: %X\n",buffer[countReadData]); } return (DÚVIDA??????); } } printf("Não leu nenhum dado"); return NULL; }

Sei (acho que sei) que tenho que retornar algo do tipo jintArray, mas não sei como.

Desde já obrigado…

[quote=Edifran]Boa tarde galera…

to quebrando a cabeça aqui, mas acho que não deve ser tão difícil, alguem pode dar uma forcinha, por favor!!!
quero retornar um vetor de inteiros para a aplicação java, minha função em C++ tá assim

JNIEXPORT jintArray JNICALL Java_DllFuntions_DllFuntions_ReadData(JNIEnv * env, jobject) { int countReadData=0;// contador para o vetor int buffer[LEN_BUFFER];// vetor que pretendo retornar if(ReadFile( hCom, BufferRecebe, LEN_BUFFER, &BytesLidos, NULL) != 0 ) { if(BytesLidos>0){ BufferRecebe[BytesLidos]='\0';// finaliza o vetor printf("Bytes lidos: %d\n",BytesLidos); for(countReadData=0;countReadData<BytesLidos;countReadData++){ buffer[countReadData]=BufferRecebe[countReadData];// armazena os dados no vetor printf("Dados lidos: %X\n",buffer[countReadData]); } return (DÚVIDA??????); } } printf("Não leu nenhum dado"); return NULL; }

Sei (acho que sei) que tenho que retornar algo do tipo jintArray, mas não sei como.

Desde já obrigado…[/quote]

Amigo de uma olhada no javadoc sobre jintArray. Você cria um objeto tipo jintArray objetoarray= (jintArray)env->NewIntArray(tamanho);
Faças as operações e retorne ele.
Tome cuidado pois alguns objetos passados do lado java para o lado nativo precisam ser recuperados e liberados.
Exemplo simples:

Método java, retorna a soma dos elementos de um array
private native float sasum_native(int n, float[] x, int incx);

Método nativo:

/*
 * Class:     acml_ACML_BlasLevel1
 * Method:    sasum_native
 * Signature: (I[FI)F
 */
JNIEXPORT jfloat JNICALL Java_acml_ACML_1BlasLevel1_sasum_1native
        (JNIEnv *env, jobject pObject, jint pN, jfloatArray pX, jint pIncx){
    
    jfloat *ptrpX = (*env)->GetFloatArrayElements(env, pX, 0);
    
    jfloat result = sasum(pN, ptrpX, pIncx);
    
    (*env)->ReleaseFloatArrayElements(env, pX, ptrpX, 0);
    
    return result;
    
}

Dá uma olhada no javadoc na parte JNI que tem muita coisa lá.

Espero ter ajudado.

Rapapel…

Valeu a dica aew, ams ainda tenho um pequeno probleminha, minha função agora ficou assim

JNIEXPORT jintArray JNICALL Java_DllFuntions_DllFuntions_ReadData(JNIEnv * env, jobject)
{
int countReadData=0;// contador para o vetor
int buffer[LEN_BUFFER];// vetor que pretendo retornar
jintArray out;// vetor que retorna pro java
jint value;// variavel de sera alocada no vetor
    if(ReadFile( hCom, BufferRecebe, LEN_BUFFER, &BytesLidos, NULL) != 0 )
    {
        if(BytesLidos>0){
                BufferRecebe[BytesLidos]='\0';// finaliza o vetor
                out = (jintArray)env->NewIntArray(BytesLidos);// define o vetor do tamanho dos bytes lidos
                printf("Bytes lidos: %d\n",BytesLidos); 
                for(countReadData=0;countReadData<BytesLidos;countReadData++){
                buffer[countReadData]=BufferRecebe[countReadData];// armazena os dados no vetor(só pra imprimir)
                value=buffer[countReadData];
                env->ReleaseIntArrayElements(out,&value,0);// atribui value a posição do vetor
                printf("Dados lidos: %X\n",buffer[countReadData]);     
                }
                return out;
        }
    }
    printf("Não leu nenhum dado");
    return NULL;
}

A saida que deveria ser assim:

1-2-3-4-5-6-7-8 (são dados lidos da porta serial)

Está saindo assim:

8-178784320-1-2-3-4-5-6-

Eu rodei varias vezes e percebi que este “178784320” não muda, mas não sei o que ele é e nem o que ele tá fazendo aew. rsrsrsrs (vo tomá uma…gelada…)

Se voce ou mais alguem ainda puder me ajudar.

Tks.

Converti seu número mágico para hexadecimal e ficou assim:
0AA80840

Como os bytes são guardados em ordem inversa, deve ser que você tem algo assim na memória:

40 08 A8 0A

Isso tem alguma significação para você?

(40 em hexa é @, 08 em hexa é Backspace, 0A em hexa é Line Feed)

Outra coisa esquisita. Nunca pensei em ler dados de uma porta serial para um array de int (cada int tem 4 bytes, não?)

Pode ser exatamente o que falaram acima.

Big endian os bytes mais significativos primeiro.
e
Little endian os bytes menos significativos primeiro.

Exemplo:
datas em big endian ficariam assim aaaa-mm-dd
em little endian dd-mm-aaaa

Java se não me engano é Big endian, então pode ser que vc esteja lendo os dados em little endian.
Então você teria que inverter a ordem desses bytes, objetos ByteBuffer tem um método order que reordena os bytes, aí vc passa obj.order(ByteBuffer.BIG_ENDIAN); para que ele reordene os bytes para big endian.

espero ter ajudado.

Outra coisa que você tem sempre de tomar cuidado. No caso do C/C++, variáveis locais (incluindo arrays) estão sempre “sujas” por default. Então você sempre tem de tomar cuidado - não é como no caso do Java, em que os arrays estão sempre “limpos” quando você os cria.

Amigos…

Acabei resolvendo (de uma maneira não muito correta) o probleminha que tava tendo, (acrescentei 2 posições no vetor da função nativa) daí no java eu uso apenas os dados que eu quero ou preciso. Tentei inicializando as variaveis com valores nulos quando possivel, mas não tive resultado. Quando aumentei o tamanho do array, as duas primeiras posições eu elimino no java, e as outras são os dados que eu preciso.

[quote]
Outra coisa esquisita. Nunca pensei em ler dados de uma porta serial para um array de int (cada int tem 4 bytes, não?)[/quote]

thingol, na verdade, os dados da porta são lidos em unsigned char (dai eu os passo para o vetor de int), poderia apenas faze-los imprimir em int, seria isso mesmo?
Ainda estou aprendendo sobre muitas coisas do java, comunicação serial, jni, etc. pode ser que alguns conceitos eu esteja entendendo errado…

Mas todas as dicas dadas por voce e Rapapel foram válidas…

Muito obrigado e, qualquer coisa eu volto a postar (ou pesquisar) aqui.

Um abraço.