JNA(Java Native Access)对JNI进行了包装,提供了一组工具类用于访问本地程序,不需要编写任何Native或JNI代码。只需要在Java接口文件中定义与本地类库中的方法结构一样的native类型的方法即可,不需要实现,JNA会自动联系Java中的接口与本地类库中的方法。
原则上来说在有本地类库时,并不需要再写本地代码,而是直接写Java代码即可,但这样做的前提是要有一个编写良好又明确标明方法的类库。如果碰到任务需要在原来本地类库的基础上进行二次包装,就不得不继续编写本地代码了,而我写的这个例子就是按照这样的步骤来的。
步骤
步骤1:
新建一个接口文件,定义需要调用的本地方法。
步骤2:
编写本地方法,用C/C++实现Java接口中的方法。方法声明前要加上 __declspec(dllexport) 即把声明的方法对外暴露。
步骤3:
生产动态库,放到对应目录下。本程序中,在Windows下,生成了dll文件,放到了JDK的bin中。
步骤4:
加载动态库,用JNA对于接口的实例来调用接口中的方法。
分步实现
新建接口类,定义接口方法
|
|
这个接口一定要继承Library的父类,对于所有的本地类库定义都源自于这个类。
编写本地方法
头文件jnainterface.h
|
|
注意方法声明的前面添加了__declspec(dllexport)。
源码文件jnainterface.cpp
|
|
生成动态库
本地代码完成后,随即就要编译为本地类库,并放到对应目录下。本程序中,在windows下,我把生成的dll文件放到了JDK的bin目录下。
加载动态库
加载动态库,用JNA对于接口的实例来调用接口中的方法。
|
|
执行上面的代码,得到下面的结果。
注意
不管是使用JNI还是JNA都要特别注意Java与本地类库中类型的对应。在JNA的网站上给出了Java与C的类型对照,可以做参考。
对于其中的boolean我也用过,在C++中因为有boolean类型,所以C++代码中可以直接用boolean。