JNI调用非静态函数段错误

我正在为Android的SDL库做一些工作,但我有一点障碍。

此函数在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); } 

在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; } 

现在这个工作,但我想编辑它以使调用非静态。 我将Java端代码更改为:

 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); } 

从函数名中删除静态。

在JNI方面,我这样做:

 /* 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; } 

有这个错误:

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

然后我重新编译c libs,清理项目并重新安装应用程序。 代码段错误在那一行,而静态版本没问题。 从查看代码,此函数中没有其他静态引用。

什么可能导致段错误? 我做了一些测试并改变了其他静态函数,抓住了获取类的env,查找函数并调用它实际上是有效的。

知道为什么会失败吗?

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

CallObjectMethod的第二个参数不应该是jclass ,而是一个jobject引用要调用该方法的该类的实例。
因此,您需要将SDLActivity实例传递给C函数,以便C函数可以将其传递给CallObjectMethod