JAVA可以将一个对象作为参数传递给本地方法,在本地方法中也可以访问这个对象的属性。不过在本地方法中调用这个对象的方法可就不会象在 JAVA 中那么随心所欲了。它必须通过本地方法传进来的第一个参数 env 进行调用,这种方式很象在JAVA中通过反射来创建对象、调用方法。
举例说明:
1、创建一个类,这个类的对象将作为参数传到本地方法中。
package test;
public class Person {
private int age;
public int getAge(){
return age;
}
public void setAge(int value){
this.age = value;
}
public Person(int age){
this.age = age;
}
}
2、创建测试类,在测试类中将创建 Person 对象,并将它作为参数传给一个本地方法,在本地方法中通过调用 getAge 方法打印年龄,通过调用 setAge 方法修改 Person 对象的年龄:
package test;
public class Test {
private native void setAge(Person person);
public static void main(String[] args){
System.load("/root/mycodes/native/obj/Test.so");
Test t = new Test();
Person p = new Person(20);
System.out.println("age = " + p.getAge());
t.setAge(p);
System.out.println("age = " + p.getAge());
}
}
3、编译 java源程序,并创建 .h 头文件
在命令行中(linux环境下):
javac -d . Person.java
javac -d . Test.java
javah test.Test
cp test_Test.h test_Test.c
4、编辑 test_Test.c之后的文件内容如下:
#ifndef __test_Test__
#define __test_Test__
#include <jni.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C"
{
#endif
JNIEXPORT void JNICALL Java_test_Test_setAge (JNIEnv *env, jobject obj1, jobject obj2)
{
jclass personCls = (*env)->GetObjectClass(env, obj2);
if(personCls == NULL){
printf("person get failed\r\n");
return;
}
jmethodID setMethod = (*env)->GetMethodID(env, personCls, "setAge", "(I)V");
jmethodID getMethod = (*env)->GetMethodID(env, personCls, "getAge", "()I");
jint age = (*env)->CallIntMethod(env, obj2, getMethod);
printf("------ before age is :%d\r\n", age);
(*env)->CallVoidMethod(env, obj2, setMethod, 30);
age = (*env)->CallIntMethod(env, obj2, getMethod);
printf("------ after age is %d\r\n", age);
}
#ifdef __cplusplus
}
#endif
#endif /* __test_Test__ */
哦,对了,忘记说在这里使用的 (*env)->GetMethodID 函数的最后一个参数应该写什么了。
这个参数应该是JAVA的类的方法的签名,它可以通过jdk的工具 javap 得到。如上面的 test.Person 类中的 setAge 方法,可以在命令行里执行:
javap -s test.Person
得到 test.Person 的所有方法的签名。
gcc -I/usr/java/jdk1.7.0/include/ -I/usr/java/jdk1.7.0/include/linux -fPIC -shared -o Test.so test_Test.c
java test.Test
输出:
age = 20
------ before age is :20
------ after age is 30
age = 30
不多解释了,程序比文字更能说明问题