记录一次项目经历,新公司开发过程中遇到了硬件对接的需求,没有接触过这方面的我一想到这些就很头大,花了几天时间来专门研究一下这个。一般硬件购买后厂家都会附赠一些开发文档,有各种语言的demo,里面其实重要的只是dll里面的dll文件和接口文档,每一个dll文件都是一个单独的函数库,里面记录着对接硬件所需要的函数。每种开发语言基本上都有对dll调用的支持,最典型的就是js的activex控件,activex控件支持js通过一个服务的clsid在页面上生成一个object对象,之后操作object对象就相当于操作dll函数库,但是特别鸡肋的是activex只支持部分ie,如果想解决兼容性问题就只能使用后台服务进行桥接。
作为一个java程序员,当然最先想到的是java代码如何操作这个dll,网上搜索到的基本上就是JNI、JNA、JNative这三种方式,这三种的功能基本上是一样的,但是相比之下,JNA的代码简洁易懂,可以说是完胜,所以这里拿JNA调用dll的demo举个栗子。
项目结构是这样的:
这里的Termb.dll是我硬件中的一个函数库,其中文档上说他有两个内置方法,
接下来发一下测试代码:
import com.sun.jna.Library;
import com.sun.jna.Native;
/**
* Test
* @author :wdq
* @date :Created in 2019/8/14 14:40
* @version: 1.0
*/
public class Test {
public static void main(String[] args) {
TerMbDll dll = init("Termb", TerMbDll.class);
System.out.println(dll.CVR_InitComm(1));
System.out.println(dll.CVR_Authenticate());
}
/**
* TerMbDll接口
* @author :wdq
* @date :Created in 2019/8/14 14:30
* @version: 1.0
*/
public interface TerMbDll extends Library {
//dll内置函数
int CVR_InitComm(int Port);
int CVR_Authenticate();
}
/**
* 装载dll接口
* @param dllPath
* @param c
* @return
*/
public static <T> T init(String dllPath,Class c){
//判断是否继承Library
if(!Library.class.isAssignableFrom(c)){
return null;
}
return (T) Native.loadLibrary(dllPath,c);
}
}
仔细品味一下jna调用dll的代码,感觉方式有点webservice的赶脚,通过classLoader完成interface和dll函数库之间的映射,我们只需要在接口中写上需要使用的方法,然后调用接口就可以了,不要太简单,有时间的小伙伴可以点jar进去看下源码,懂了源码可以在基础上再封装一下。贴一下我的pom文件:
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.1.0</version>
</dependency>