2010-04-15 5 views
5

J'ai besoin d'aide pour transmettre des données binaires dans Java. J'essaye d'employer jbytearray mais quand les données entrent dans Java il semble corrompu. Quelqu'un peut-il me donner un coup de main?JNI Flux de données binaires de C++ vers Java

Voici un petit exemple de code. D'abord le natif côté ++ C:

printf("Building audio array copy\n"); 
jbyteArray rawAudioCopy = env->NewByteArray(10); 
jbyte toCopy[10]; 
printf("Filling audio array copy\n"); 
char theBytes[10] = {0,1,2,3,4,5,6,7,8,9}; 
for (int i = 0; i < sizeof(theBytes); i++) { 
    toCopy[i] = theBytes[i]; 
} 


env->SetByteArrayRegion(rawAudioCopy,0,10,toCopy); 
printf("Finding object callback\n"); 
jmethodID aMethodId = env->GetMethodID(env->GetObjectClass(obj),"handleAudio","([B)V"); 
if(0==aMethodId) throw MyRuntimeException("Method not found error",99); 
printf("Invoking the callback\n"); 
env->CallVoidMethod(obj,aMethodId, &rawAudioCopy); 

et la méthode de rappel Java:

public void handleAudio(byte[] audio){ 
    System.out.println("Audio supplied to Java [" + audio.length + "] bytes"); 
    byte[] expectedAudio = {0,1,2,3,4,5,6,7,8,9}; 
    for (int i = 0; i < audio.length; i++) { 
     if(audio[i]!= expectedAudio[i]) 
      System.err.println("Expected byte " + expectedAudio[i] 
        + " at byte " + i + " but got byte " + audio[i]); 
     else System.out.print('.'); 
    } 
    System.out.println("Audio passed back accordingly!"); 
} 

Je reçois la sortie suivante lorsque le rappel est invoqué:

library loaded! 
Audio supplied to Java [-2019659176] bytes 
Audio passed back accordingly! 
+0

Je pense avoir trouvé mon problème ... Cet appel: env-> CallVoidMethod (obj, aMethodId, & rawAudioCopy); passait par ref au lieu de par valeur. Passage à ceci: env-> CallVoidMethod (obj, aMethodId, rawAudioCopy); Semble résoudre le problème. Y a-t-il un bon manuel de référence et des exemples pour me soutenir? Je suis vraiment mal à l'aide ici. – Cliff

Répondre

1

Après avoir corrigé mon erreur ci-dessus Je suis maintenant à la recherche du moyen le plus efficace de recopier des tableaux d'octets bruts en Java. Ce que j'ai ci-dessus me semble un peu moins qu'idéal puisque je prévois de soutenir un grand nombre de copies répétées. J'ai expérimenté en passant le tableau char directement à l'appel setByteArrayRegion qui semble fonctionner dans ce cas simple mais je me demande si j'ai besoin d'effectuer un épinglage. Comment cela se passe-t-il lorsque vous créez de nouveaux tableaux sur le côté natif? Est-ce que j'appelle simplement getByteArrayRegion avec un FALSE après l'ensemble? Puis-je dés-épingler après la fin de l'appel en Java? Existe-t-il des exemples en ligne de transfert de données binaires brutes de haute performance vers Java, que je peux apprendre?

1

au lieu de

env->CallVoidMethod(obj,aMethodId, &rawAudioCopy); 

essayer

env->CallVoidMethod(obj,aMethodId, rawAudioCopy, 0 , 10);