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

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


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


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

©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值