JAVA本地方法调用(2)数组参数传递

JAVA可以把数组作为参数传递给本地方法,在本地方法中可以访问数组中的元素。

不过,在本地方法却不能直接访问传进来的数组,需要进行一定的转换。举例说明:


1、创建 JAVA 类:

package test;
 
public class Test {
    public native void copy(int[] a, int[] b);
    
    public static void main(String[] args){
        System.load("/root/mycodes/native/intArrayCpy/Test.so");
        
        Test obj = new Test();
        int[] a = new int[]{1, 2, 3, 4, 5};
        int[] b = new int[a.length];
        
        obj.copy(a, b);
        String pre = "\r\n\r\n";
        for(int i : b){
            System.out.print(pre + i);
            pre = ", ";
        }
        System.out.println();
    }
}

2、编译并生成 .h 文件:

javac -d . Test.java
javah -jni test.Test



3、编写 c 源程序,可以将 javah 生成的文件拷贝成 c 文件,然后在上面修改:

cp test_Test.h test_Test.c
vim test_Test.c


修改之后的C源程序如下:


#include <jni.h>
/* Header for class test_Test */
 
#ifndef _Included_test_Test
#define _Included_test_Test
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     test_Test
 * Method:    copy
 * Signature: ([I[I)V
 */
JNIEXPORT void JNICALL Java_test_Test_copy
  (JNIEnv * env, jobject obj, jintArray pA, jintArray pB){
    int a[5];
    int b[5];
    int i;
    jsize size = (*env)->GetArrayLength(env, pA);
    (*env)->GetIntArrayRegion(env, pA, 0, size, a);
    for(i=0; i<5; i++){
        b[i] = a[i];
    }
    
    (*env)->SetIntArrayRegion(env, pB, 0, 5, b);
}
 
#ifdef __cplusplus
}
#endif
#endif

4、编译并运行:

 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



注意在 Test.java 文件中,System.load 中的参数是由上面的 gcc 命令生成的 so 文件的全路径


观察发现,如果要访问由JAVA虚拟机传进来的数组,必须调用 env 提供的函数进行转换。在 jdk 安装目录下查找 jni.h 文件,可以发现jdk其实为我们定义了很多转换函数。比如上面的代码中用到了:

GetArrayLength 得到传入的数组参数的元素个数

GetIntArrayRegion 将JAVA虚拟机传进来的整数数组元素拷贝到本地的整数数组

SetIntArrayRegion 将本地的整数数组拷贝到传进来的参数中,以便传回

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

抵扣说明:

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

余额充值