Je développe une bibliothèque Android de bas niveau qui doit traiter les signaux audio dans le JNI pour économiser le coût de traitement. Puisqu'il me faudra peut-être faire plusieurs fois référence au même tampon audio, je décide donc de garder un pointeur de structure pour envelopper ces tampons audio dans C (afin que plusieurs fonctions C puissent accéder au même tampon audio). J'utilise principalement l'idée empruntée de here et here.Passer le pointeur comme jlong dans JNI/Android-NDK ne fonctionne pas()
Cependant, les choses ne fonctionnent pas comme prévu. Mon programme plante après une autre fonction essaie d'accéder à la mémoire allouée par les précédents appels jni.
Voici l'exemple JNI pour montrer ce problème:
struct AddAudioRet{
int chCnt;
int traceCnt;
int sampleCnt;
float ***data; // data[chIdx][traceIdx][sampleIdx]; -> reverse order of the Matlab data structure
};
extern "C" jlong Java_XXX_XXX_addAudioSamples(JNIEnv *env, jobject obj, jbyteArray audioToAdd) {
// some processing codes
AddAudioRet *ret;
ret = (AddAudioRet *)malloc(sizeof(AddAudioRet));
ret->chCnt = ps->recordChCnt; // 2
ret->traceCnt = repeatToProcess; // 3
ret->sampleCnt = as->signalSize; // 2400
jlong retLong = (jlong)ret;
mylog("retLong (jlong) = %ld", retLong);
AddAudioRet *temp = (AddAudioRet *)retLong;
mylog("temp's chCnt %d, traceCnt %d, sampleCnt = %d", temp->chCnt, temp->traceCnt, temp->sampleCnt);
return retLong; // return the memory address of the ret structure
}
extern "C" void Java_XXX_XXX_debugDumpAddAudioRet(JNIEnv *env, jobject obj, jlong addAudioRet) {
debug("addAudioRetLong = %ld", addAudioRet);
debug("ret's chCnt %d, traceCnt %d, sampleCnt = %d", r->chCnt, r->traceCnt, r->sampleCnt);
}
Dans Android, j'appelle les fonctions JNI comme ceci:
public native int addAudioSamples(byte[] audioToAdd);
public native void debugDumpAddAudioRet(long addAudioRet);
int testJNI(byte[] data) {
long ret = addAudioSamples(data);
debugDumpAddAudioRet(ret);
}
Résultats:
retLong (jlong) = 547383410656
temp's chCnt 2, traceCnt 3, sampleCnt = 2400
// *** dumped by the debug check ***
addAudioRetLong = 1922564064
ret's chCnt 55646750, traceCnt 82374663, sampleCnt = 1831675530
Je sais le problème est la conversion de type entre l'adresse mémoire et jlong puisque les sorties d'adresse mémoire ne sont pas identiques. Cependant, je ne sais pas comment cela se passe, si la conversion n'est pas autorisée/légale, je devrais obtenir l'erreur quand je jette (trivialement) la variable "temp", non?
Peut-être un problème de taille. Les pointeurs sont 64 bits, mais long a tendance à être seulement 32 bits - généralement, vous devez utiliser un long long pour stocker un pointeur. –
Salut Gabe, je suppose que c'est aussi le problème de taille, mais j'ai fait imprimer le sizeof jlong (= 8 octets) et je suis certain que java long est> 8-byte aussi (par exemple, long testLong = 547383410656L sera ok). –