Java JNI - VIOLATION D'ACCÈS AUX EXCEPTIONS lors du retour de jintArray
Une chose vraiment bizarre se produit dans ce code
JNIEXPORT jintArray JNICALL Java_jsdr_SdrLibrary_getTunerGains
(JNIEnv * env, jclass obj, jlong pointer) {
rtlsdr_dev_t * dev;
int * gains;
jintArray ji;
jint * buff;
int i;
int size;
dev = (rtlsdr_dev_t *) pointer;
size = rtlsdr_get_tuner_gains(dev, gains);
if (size <= 0)
.. throws an error, irrelevant code ..
buff = (jint *) malloc(size * sizeof(jint));
for (i = 0; i < size; i++) buff[i] = gains[i];
ji = (*env)->NewIntArray(env, size);
(*env)->SetIntArrayRegion(env, ji, 0, size, buff);
return ji;
}
La méthode renvoie en fait un résultat que je peux gérer en Java avec
System.out.println(printArray(SdrLibrary.getTunerGains(pointer)));
Où printArray est juste un simple
public static String printArray(int[] arr) {
String buff = "["+arr[0];
for (int i = 1; i < arr.length; i++) buff+=", "+arr[i];
return buff+"]";
}
La sortie est la suivante
[-10, 15, 40, 65, 90, 115, 140, 165, 190, 215, 240, 290, 340, 420, 430, 450, 470, 490]
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6d86c2ff, pid=7160, tid=5880
#
# JRE version: 6.0_31-b05
# Java VM: Java HotSpot(TM) Client VM (20.6-b01 mixed mode, sharing windows-x86 )
# Problematic frame:
# V [jvm.dll+0x7c2ff]
#
# An error report file with more information is saved as:
# C:\Users\Marto\workspace\JSDR\hs_err_pid7160.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
Comme vous pouvez le voir, il renvoie un résultat mais immédiatement après, le JM se bloque et aucune autre ligne n'est exécutée. J'apprécierais certainement toute aide! Merci!!!!
EDIT: Si je supprime l'appel à rtlsdr_get_tuner_gains et au lieu d'initialiser manuellement le tableau gains, aucune erreur n'est observée. Puisque cette méthode est à l'intérieur d'une dll, puis-je l'empêcher de planter le JNI?
1 answers
J'ai découvert la source de l'erreur. Il s'avère que la bibliothèque d'origine n'alloue pas le tampon qui lui est transmis, ce qui entraîne l'écrasement de la mémoire qui n'est pas détenue par le JNI (grâce à QuantumMechanic pour me donner l'idée simple de regarder réellement la source de la bibliothèque).
La solution était assez simple. Changer ceci
int * gains;
À ce
int gains[30];