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

来源:互联网 发布:php redis抢红包源代码 编辑:程序博客网 时间:2024/06/06 02:40

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.javajavah -jni test.Test



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

cp test_Test.h test_Test.cvim test_Test.c


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


#include <jni.h>/* Header for class test_Test */ #ifndef _Included_test_Test#define _Included_test_Test#ifdef __cplusplusextern "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.cjava test.Test



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


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

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

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

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

原创粉丝点击