JNA实际上是基于JNI封装的,其在应用的时候更加方便,但效率相对低,主要适合对实时性要求不高的场合。JNI虽然效率高,但是应用不方便。JavaCPP提供了在Java中高效访问本地C++的方法。采用JNI技术实现,支持包括Android系统在内的所有Java实现。
在本例中,DLL源代码进行了一些修改,用一个TAdd.h表示所有代码,更加简单了:
namespace TAdd {
class Add {
public:
int add(int a, int b) { return a + b; }
};
}
从网址http://bytedeco.org/download/下载JavaCPP的 binary archive,取出其中的javacpp.jar。
编写Java程序,建立一个Java类来描述DLL的函数结构,先引入.h文件和namespace。
@Platform(include= "TAdd.h")
@Namespace("TAdd")
在类TAdd的实现中添加函数,还是先加载DLL
static { Loader.load(); }
添加构造函数
public Add() { allocate(); }
声明类的函数的结构
private native int add(int a, int b);
定义好之后,将TAdd.java、TAdd.h、javacpp.jar放到同一个目录下,启动visual studio 2015的“VS2015 x86本机工具命令提示符”,打开的命令行窗口中,转到TAdd.h源码目录下,执行javac -cp javacpp.jar TAdd.java
生成class文件,执行java -jar javacpp.jar TAdd
生成DLL文件(编译DLL源码)。生成文件在一个名为“windows-x86”的子目录中。
注:这里采用x86编译,是因为我的jdk是32位的。如果jdk是64位的,可以采用x64编译,与jdk位数匹配。
创建一个Java Project,在project中创建一个lib文件夹,将javacpp.jar加入到其中,project中右击javacpp.jar文件,Build Path->Add to Build Path加载javacpp.jar。
将生成的“windows-x86”目录整体拷贝到java project的src目录下,同时将TAdd.java也import到工程中,为其添加主函数,调用DLL函数。
int sum = new Add().add(8,9);
注:如果TAdd.java本来就包含主函数,可在生成DLL后,直接通过java -cp javacpp.jar TAdd
来实现调用DLL函数。
JavaCPP调用DLL效率极高,测试表名甚至高于采用JNI调用的结构,也许我的JNI写的有问题,不过足够证明JavaCPP的高效率。
完整示例代码可在http://download.csdn.net/download/ezhchai/10155929中下载,起名字为“最简单的JavaCPP调用DLL”,致敬那个勤奋刻苦的“雷神”。