I am doing some work with the SDL library for android but i'm having a little obstacle.
This function is defined in 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);
}
on the JNI/C side:
/* 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 < number) {
jint* elements = (*env)->GetIntArrayElements(env, array, NULL);
if (elements) {
int i;
*ids = SDL_malloc(number * sizeof (**ids));
for (i = 0; i < number; ++i) { /* not assuming sizeof (jint) == sizeof (int) */
(*ids)[i] = elements[i];
}
(*env)->ReleaseIntArrayElements(env, array, elements, JNI_ABORT);
}
}
(*env)->DeleteLocalRef(env, array);
}
return number;
}
Now this works, but I would like to edit this to make the call non static. I changed the Java side code to this:
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);
}
removing the static from the function name.
On the JNI side I do this:
/* 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"); <-- i reach this line successfully
jintArray array = (*env)->CallObjectMethod(env, clazz, javamethod, sources); <-- this line segfaults
__android_log_print(ANDROID_LOG_INFO, "SDL", "made it to SDL_android.c line 1418");
if(array)
{
__android_log_print(ANDROID_LOG_INFO, "SDL", "SUCCESS GETTING array line 1421");
}
else
{
__android_log_print(ANDROID_LOG_INFO, "SDL", "FAILED GETTING array line 1425");
}
//------------
//jintArray array = (jintArray) (*env)->CallStaticObjectMethod(env, mActivityClass, mid, sources);
int number = 0;
*ids = NULL;
if (array) {
number = (int) (*env)->GetArrayLength(env, array);
if (0 < number) {
jint* elements = (*env)->GetIntArrayElements(env, array, NULL);
if (elements) {
int i;
*ids = SDL_malloc(number * sizeof (**ids));
for (i = 0; i < number; ++i) { /* not assuming sizeof (jint) == sizeof (int) */
(*ids)[i] = elements[i];
}
(*env)->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;
}
with this error:
09-19 22:40:53.514: A/libc(29636): Fatal signal 11 (SIGSEGV) at 0x00000001 (code=1), thread 29650 (Thread-22463)
I then recompile the c libs, clean the project and reinstall the app. The code segfaults at that line while the static version is fine. From looking around the code, there's no other static references in this function.
What could be causing that segfault? I've done a few tests and changing other static functions, grabbing the env getting the class, looking up the function and calling it actually works.
Any idea why this one will fail?