java 可以通过本地方法调用 C 语言写的子程序。不过,C中的子程序并不能直接被JAVA调用,而必须由JAVA定义对C的访问接口。
当然,我说的这个接口不是java语言中的接口,而是java和C语言之间的调用规范。
1、写一个 java 类,在类中定义一个本地方法
package test;
public class Add {
public native int add(int a, int b);
public static void main(String[] args){
System.load("/root/mycodes/native/add/Add.so");
Add obj = new Add();
int a = 10;
int b = 20;
System.out.println("a + b = " + obj.add(a, b));
}
}
2、在终端上编译这个类:
javac -d . Add.java
将会生成 test 目录,并在test 目录下生成 Add.class 文件
3、再用 javah 生成一个 .h 文件:
javah test.Add
将会生成一个名为 test_Add.h 文件,在这个文件中定义了一个名为Java_test_Add_add 的方法,前两个参数暂时不管它,后两个参数其实就是在 Add.java 中定义的两个参数
4、现在要做的是写一个 C程序文件,实现在 test_Add.h 中定义的方法。这个程序的功能很简单,只是返回两个整数的和,所以可以把 test_Add.h 文件复制一份,稍微改一下就可以了:
cp test_Add.h test_Add.c
最后 test_Add.c 中的内容:
/* DO NOT EDIT THIS FILE - it is machine generated */
#ifndef __test_Add__
#define __test_Add__
#include <jni.h>
#ifdef __cplusplus
extern "C"
{
#endif
JNIEXPORT jint JNICALL Java_test_Add_add (JNIEnv *env, jobject pObj, jint a, jint b){
return a + b;
}
#ifdef __cplusplus
}
#endif
#endif /* __test_Add__ */
5、最后要做的就是把 C 编译成 .so,供 java 调用:
gcc -I/usr/java/jdk1.7.0/include/ -I/usr/java/jdk1.7.0/include/linux -fPIC -shared -o Add.so test_Add.c
其中 /usr/java/jdk1.7.0 是我的jdk安装目录,Add.so 是要生成的目录文件,test_Add.c 是被编译的C源程序文件
编译成将会在当前目录下生成 Add.so 文件
然后执行
java test.Add
输出:a + b = 30
当然,在Add.java中,System.load 方法中的参数是 C 编译之后的.so文件,如果您的目录结构和我的不一样,要作相应的修改。