JNI提供了很多API用来传递对象从JAVA到C, 一般比较普通的就是传递原始类型,或者String,如果传递的对象中包含其他类型的对象,过程就有点复杂了。先上代码吧.
public class Container {
private String hello;
private Map<String, String> parameterMap = new HashMap<String, String>();
public Map<String, String> getParameterMap() {
return parameterMap;
}
}
这个对象包括两个属性,hello和parameterMap,hello是String类型的,而parameterMap是一个Map类型的。
使用native的方法类传递:
public class MyClazz {
public doProcess() {
Container container = new Container();
container.getParameterMap().put("foo","bar");
manipulateMap(container);
}
public native void manipulateMap(Container container);
}
这里将Container对象作为参数,他的实现是在底层的C代码中完成的:
JNIEXPORT jint JNICALL Java_MyClazz_manipulateMap(JNIEnv *env, jobject selfReference, jobject jContainer) { // initialize the Container class jclass c_Container = (*env)->GetObjectClass(env, jContainer); // initialize the Get Parameter Map method of the Container class jmethodID m_GetParameterMap = (*env)->GetMethodID(env, c_Container, "getParameterMap", "()Ljava/util/Map;"); // call said method to store the parameter map in jParameterMap jobject jParameterMap = (*env)->CallObjectMethod(env, jContainer, m_GetParameterMap); // initialize the Map interface jclass c_Map = env->FindClass("java/util/Map"); // initialize the Get Size method of Map jmethodID m_GetSize = (*env)->GetMethodID(env, c_Map, "size", "()I"); // Get the Size and store it in jSize; the value of jSize should be 1 int jSize = (*env)->CallIntMethod(env, jParameterMap , m_GetSize); // define other methods you need here. }
上面的代码没有完成,不过可以顺利得到HashMap的size. 如果需要遍历这个HashMap,还可以调用HashMap的其他方法。
这里需要注意的是,如果传递的object里面有非原始类型的数据类型,就需要做一些转换,转换成C能认识的类型。可以通过
jclass c_Map = env->FindClass("java/util/Map");
这个方法就是在C层获得一个Map的类型,然后我们可以得到这个类相应的方法:
jmethodID m_GetSize = (*env)->GetMethodID(env, c_Map, "size", "()I");
然后去调用它:
int jSize = (*env)->CallIntMethod(env, c_Map, m_GetSize);
如果希望返回一个Java层的对象,也可以使用这个方法,是不是很简单。。。。