JNI_OnUnload()当VM释放该组件时被调用,JNI_OnUnload()函数的作用与JNI_OnLoad()对应,因此在该方法中进行善后清理,资源释放的动作最为合适。
Java代码和使用哪种方式实现JNI无关,如下所示:
class MyJavaClass
{
public int iValue;
public void Squa(){iValue = iValue*iValue;}
}
public class RegisterNativesTest
{
static{
System.load("/home/zmh/workspace/RegisterNativesTest/lib/libCallClass.so");
}
public static void main(String[] args)
{
RegisterNativesTest app = new RegisterNativesTest();
MyJavaClass obj = new MyJavaClass();
obj.iValue = 10;
System.out.println("Before callCustomClass: " + obj.iValue);
app.callCustomClass(obj);
System.out.println("After callCustomClass: " + obj.iValue);
}
private native void callCustomClass(MyJavaClass obj);
}
void callCustomClass(JNIEnv* env, jobject, jobject obj)
{
jclass cls = env->GetObjectClass(obj);
jfieldID fid = env->GetFieldID(cls, "iValue", "I");
jmethodID mid = env->GetMethodID(cls, "Squa", "()V");
int value = env->GetIntField(obj, fid);
printf("Native: %d\n", value);
env->SetIntField(obj, fid, 5);
env->CallVoidMethod(obj, mid);
value = env->GetIntField(obj, fid);
printf("Native:%d\n", value);
}
static JNINativeMethod s_methods[] = {
{"callCustomClass", "(LMyJavaClass;)V", (void*)callCustomClass},
};
int JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env = NULL;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK)
{
return JNI_ERR;
}
jclass cls = env->FindClass("LRegisterNativesTest;");
if (cls == NULL)
{
return JNI_ERR;
}
int len = sizeof(s_methods) / sizeof(s_methods[0]);
if (env->RegisterNatives(cls, s_methods, len) < 0)
{
return JNI_ERR;
}
return JNI_VERSION_1_4;
}
/*
* used in RegisterNatives to describe native method name, signature,
* and function pointer.
*/
typedef struct {
char *name;
char *signature;
void *fnPtr;
} JNINativeMethod;
name是java中定义的native函数的名字,fnPtr是函数指针,也就是C++中java native函数的实现。signature是java native函数的签名,可以认为是参数和返回值。比如(LMyJavaClass;)V,表示函数的参数是LMyJavaClass,返回值是void。对于基本类型,对应关系如下:
字符 Java类型 C/C++类型 V void void Z jboolean boolean I jint int J jlong long D jdouble double F jfloat float B jbyte byte C jchar char S jshort short
数组则以"["开始,用两个字符表示,比如int数组表示为[I,以此类推。