前言
正如标题所说,Jni(Java Native Interface) 把 Java 和 C/C++之间联系起来了。这样的话,Java可以直接调用C/C++语言编写的代码。Jni的主要问题在于破坏JVM的跨平台特征。Jni的优点在于:C/C++运行快一些;可以利用C/C++的历史遗留代码;有时候只能用C/C++来完成项目需求。
图:Java jni 示意图,引自华清远见的新浪博客。
Talk is cheap, show me the code. 下面的代码是在Linux环境下写的。总的来说,是一个五步曲,按顺序依次分为:Java代码、编译Java、C代码、编译C、运行。在关键部分做了详细的说明。
注:使用Linux操作系统,下面的第一~第五步中的文件和操作都是在同一个目录/home/Jni_example下面,即项目的根目录。
第一步:Java代码
// 文件:/home/Jni_example/Hello.java
public class Hello
{
public native void sayHi(String who, int times);
static
{
System.loadLibrary("HelloC");
}
public static void main(String[] args)
{
Hello hello = new Hello();
System.out.println("Say hello to " + args[0] + " " + args[1] + " times." );
hello.sayHi(args[0], Integer.parseInt(args[1]));
}
}
Java程序通过如下方法调用C的代码:
public native void sayHi(String who, int times);
Java程序加载C语言编写的动态链接库需要loadLibrary。这个动态库不能随便自己起名字!如果你在Java代码中System.loadLibrary(“HelloC”); 那么C的动态库的名字必须是libHelloC.so,从”HelloC” 到 “libHelloC.so”,一个字母不能多,一个字母不能少。
static
{
System.loadLibrary("HelloC");
}
其实还可以使用 System.load()方法,请看此博客最底下的讨论部分。
第二步:编译Java
前提是,你要安装好 Java JDK,不然没有 javac 和 javah 这两个编译程序
javac Hello.java // 编译 Java 程序,生成Hello.class
javah -jni Hello // 产生一个 Hello.h 头文件,这个头文件包含了关键的native接口函数的声明。
javah 自动生成的Hello.h头文件如下:
// 文件:/home/Jni_example/Hello.h
/* DO NOT EDIT