一步步教你如何对接dll运行库,Java的JNA开发-初探

1,634 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。


提到物联网开发中用到最多的方式,除了TCP,还得是DLL调用,因为很多第三方PLC不支持二次嵌入开发,只能使用他们给定的调用DLL进行访问通信,这就不得不用到Java中的JNA(JNI)技术了。

1. 什么是JNA

谈到JNA之前,他还有个前辈叫JNI,用于访问本地native方法,是jdk原生自带的组件,而JNA,是建立在JNI基础之上,对JNI的进一步封装,让对DLL的接入开发更佳快捷友好。

2. 开发准备

2.1 maven引入

        <dependency>
            <groupId>net.java.dev.jna</groupId>
            <artifactId>jna</artifactId>
            <version>5.3.1</version>
        </dependency>

2.2 引入dll文件

在项目的resources目录下分别建立w32-x86(32位dll库)和w32-x86-64(64位dll库) 在这里插入图片描述

3. 开发Library

3.1 JNA数据类型对应关系

Native TypeJava TypeNative Representation
charbyte8-bit integer
wchar_tchar16/32-bit character
shortshort16-bit integer
intint32-bit integer
intboolean32-bit integer (customizable)
long, __int64long64-bit integer
long longlong64-bit integer
floatfloat32-bit FP
doubledouble64-bit FP
pointerBuffer/Pointer
char*String
wchar_t*WString
char**String[]
wchar_t**WString[]
void*Pointer
void **PointerByReference
int&IntByReference
int*IntByReference
structStructure
(*fp)()Callback
variesNativeMapped
long*NativeLong

3.2 定义Library接口

要在Java中先定义dll的方法接口,方法名,返回值,参数列表类型必须和dll中提供的方法保持一致

public interface DemoLibrary extends Library {
  int sum(int a,int b);
}

3.3 创建对象使用

DemoLibrary demoLibrary = Native.load("DLL_NAME",DemoLibrary.class);
int result=demoLibrary.sum(2,3);

DLL_NAME仅限dll的名称,dll文件放在resources对应的win32目录下,不带dll后缀,不带目录,jna自行寻找加载。

3.4 dll库加载规则

1). Native.load方法里写入dll完整路径

2). 如果是jni开发,则需要指定dll库的完整路径,或者使用

// 设置path路径,需要先查询当前的path,然后追加在后面,不建议直接set
// 追加后的效果相当于在系统变量里添加了path值
System.setProperty("java.library.path", your_library_dir);

3). 只输入DLL库名称,则会在下列目录中查找,找不到则报错:

目录使用环境
当前类目录仅开发环境,打成jar后无效
resources中的win32目录仅开发环境,打成jar后无效
当前运行目录开发+生产环境
jdk的bin目录开发+生产环境
系统system32目录开发+生产环境

此类寻找规则依据jna的版本而定,在早先的jna版本里不支持resource中的win32目录查找

4. 打包发布

因为dll库的特殊依赖关系,需要将dll一起打包,我常用的做法是

  • resources中放入dll文件一起打包
  • 所有的Native.load写入完整路径
  • 项目启动后在调用Native.load前先将resource中的dll文件复制到运行磁盘的指定目录下(不可直接访问jar包resource中的文件)

使用这种打包方案就能将dll文件同步到每个版本的jar包且不需要再到其他地方维护dll文件,但缺点就是打出来的jar包会相对较大


有兴趣的小伙伴可以关注公众号【暴走的怪兽君】,常更新Java干货资讯,免费提供大量教程和工具下载。