JAVA本地方法调用(3)对象参数传递

来源:互联网 发布:剑三商城数据导入非法 编辑:程序博客网 时间:2024/06/03 19:21

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 __cplusplusextern "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 的所有方法的签名。


5、编译(linux环境下)运行:

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


不多解释了,程序比文字更能说明问题

原创粉丝点击