Segments de fonction non statiques appelant JNI

Je travaille avec la bibliothèque SDL pour Android, mais je rencontre un petit obstacle.

Cette fonction est définie en Java:

/** * This method is called by SDL using JNI. * @return an array which may be empty but is never null. */ public static int[] inputGetInputDeviceIds(int sources) { int[] ids = InputDevice.getDeviceIds(); int[] filtered = new int[ids.length]; int used = 0; for (int i = 0; i < ids.length; ++i) { InputDevice device = InputDevice.getDevice(ids[i]); if ((device != null) && ((device.getSources() & sources) != 0)) { filtered[used++] = device.getId(); } } return Arrays.copyOf(filtered, used); } 

côté JNI / C:

 /* returns number of found touch devices as return value and ids in parameter ids */ int Android_JNI_GetTouchDeviceIds(int **ids) { JNIEnv *env = Android_JNI_GetEnv(); jint sources = 4098; /* == InputDevice.SOURCE_TOUCHSCREEN */ jmethodID mid = (*env)->GetStaticMethodID(env, mActivityClass, "inputGetInputDeviceIds", "(I)[I"); jintArray array = (jintArray) (*env)->CallStaticObjectMethod(env, mActivityClass, mid, sources); int number = 0; *ids = NULL; if (array) { number = (int) (*env)->GetArrayLength(env, array); if (0 GetIntArrayElements(env, array, NULL); if (elements) { int i; *ids = SDL_malloc(number * sizeof (**ids)); for (i = 0; i ReleaseIntArrayElements(env, array, elements, JNI_ABORT); } } (*env)->DeleteLocalRef(env, array); } return number; } 

Maintenant, cela fonctionne, mais je voudrais modifier ceci pour rendre l’appel non statique. J’ai changé le code côté Java en ceci:

 public int[] inputGetInputDeviceIds(int sources) { int[] ids = InputDevice.getDeviceIds(); int[] filtered = new int[ids.length]; int used = 0; for (int i = 0; i < ids.length; ++i) { InputDevice device = InputDevice.getDevice(ids[i]); if ((device != null) && ((device.getSources() & sources) != 0)) { filtered[used++] = device.getId(); } } return Arrays.copyOf(filtered, used); } 

supprimer la statique du nom de la fonction.

Du côté de JNI, je fais ceci:

 /* returns number of found touch devices as return value and ids in parameter ids */ int Android_JNI_GetTouchDeviceIds(int **ids) { JNIEnv *env = Android_JNI_GetEnv(); jint sources = 4098; /* == InputDevice.SOURCE_TOUCHSCREEN */ //jmethodID mid = (*env)->GetStaticMethodID(env, mActivityClass, "inputGetInputDeviceIds", "(I)[I"); //------------ jclass clazz = (*env)->FindClass(env, "org/libsdl/app/SDLActivity"); if (clazz == 0) { __android_log_print(ANDROID_LOG_INFO, "SDL", "find class failed SDL_android.c line 1409"); return; } jmethodID javamethod = (*env)->GetMethodID(env, clazz, "inputGetInputDeviceIds", "(I)[I"); if (javamethod == 0) { __android_log_print(ANDROID_LOG_INFO, "SDL", "find non static method failed SDL_android.c line 1414"); return; } __android_log_print(ANDROID_LOG_INFO, "SDL", "SUCCESS GETTING JNI METHOD FROM ENV SDL_android.c line 1416"); CallObjectMethod(env, clazz, javamethod, sources); CallStaticObjectMethod(env, mActivityClass, mid, sources); int number = 0; *ids = NULL; if (array) { number = (int) (*env)->GetArrayLength(env, array); if (0 GetIntArrayElements(env, array, NULL); if (elements) { int i; *ids = SDL_malloc(number * sizeof (**ids)); for (i = 0; i ReleaseIntArrayElements(env, array, elements, JNI_ABORT); } } (*env)->DeleteLocalRef(env, array); } __android_log_print(ANDROID_LOG_INFO, "SDL", "reached the end of inputGetInputDeviceIds func"); return number; } 

avec cette erreur:

 09-19 22:40:53.514: A/libc(29636): Fatal signal 11 (SIGSEGV) at 0x00000001 (code=1), thread 29650 (Thread-22463) 

Je recomstack ensuite les bibliothèques c, nettoie le projet et réinstalle l’application. Le code segfaults sur cette ligne alors que la version statique convient. En regardant autour du code, il n’y a pas d’autres références statiques dans cette fonction.

Quelle pourrait être la cause de cette erreur de segmentation? J’ai fait quelques tests et changé d’autres fonctions statiques, saisissant l’environnement et obtenant la classe, recherchant la fonction et l’appelant fonctionnant réellement.

Une idée pourquoi celui-ci va échouer?

 jintArray array = (*env)->CallObjectMethod(env, clazz, javamethod, sources); ^^^^^ This is incorrect 

Le deuxième argument de CallObjectMethod ne doit pas être une jclass , mais un object de jobject référence à l’instance de cette classe sur laquelle vous voulez appeler la méthode.
Vous devrez donc transmettre l’instance SDLActivity à votre fonction C pour que celle-ci puisse la transmettre à CallObjectMethod .