I've got some C functions which I am calling through JNI which take a pointer to a structure, and some other functions which will allocate/free a pointer to the same type of structure so that it is a bit easier to deal with my wrapper. Surprisingly, the JNI documentation says very little about how to deal with C structures.
My C header file looks like so:
typedef struct _MyStruct {
float member;
} MyStruct;
MyStruct* createNewMyStruct();
void processData(int *data, int numObjects, MyStruct *arguments);
The corresponding JNI C wrapper file contains:
JNIEXPORT jobject JNICALL
Java_com_myorg_MyJavaClass_createNewMyStruct(JNIEnv *env, jobject this) {
return createNewMyStruct();
}
JNIEXPORT void JNICALL
Java_com_myorg_MyJavaClass_processData(JNIEnv *env, jobject this, jintArray data,
jint numObjects, jobject arguments) {
int *actualData = (*env)->GetIntArrayElements(env, data, NULL);
processData(actualData, numObjects, arguments);
(*env)->ReleaseIntArrayElements(env, data, actualData, NULL);
}
...and finally, the corresponding Java class:
public class MyJavaClass {
static { System.loadLibrary("MyJniLibrary"); }
private native MyStruct createNewMyStruct();
private native void processData(int[] data, int numObjects, MyStruct arguments);
private class MyStruct {
float member;
}
public void test() {
MyStruct foo = createNewMyStruct();
foo.member = 3.14159f;
int[] testData = new int[10];
processData(testData, 10, foo);
}
}
Unfortunately, this code crashes the JVM right after hitting createNewMyStruct()
. I'm a bit new to JNI and have no idea what the problem could be.
Edit: I should note that the C code is very vanilla C, is well-tested and was ported from a working iPhone project. Also, this project is using the Android NDK framework, which lets you run native C code from an Android project from within JNI. However, I don't think that this is strictly an NDK issue... it seems like a JNI setup/initialization error on my part.
You need to create a Java class with the same members as C struct, and 'map' them in the C code via methods env->GetIntField, env->SetIntField, env->GetFloatField, env->SetFloatField, and so on - in short, lots of manual labor, hopefully there already exist programs that do it automatically: JNAerator (http://code.google.com/p/jnaerator) and SWIG (http://www.swig.org/). Both have their pros and cons, the choice is up to you.