问题

我在win10使用jna调dll格式的C++动态库,结果一直报java.lang.UnsatisfiedLinkError: Unable to load library:Native library not found in resource path,报错代码是下面这一行的load方法:

JnaLibrary INSTANCE = Native.load("JNA", JnaLibrary.class);

jna版本:

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

常见原因

网上的博客提的最多的是下面这两个原因:

  1. jvm位数和编译dll文件的环境的位数不一样,比如一个是64位,一个是32位。
  2. Native.load用的是相对路径,但dll文件没放在System.getProperty("java.library.path")所返回的目录列表之一。

好多人排除了上述两个原因还是不行,其实还有个鲜有人提的原因:

  1. 缺少jna所需要的系统库。

对于原因3,报错信息其实已经提示了Native library not found in resource path,只不过大家都忽略了。我也是折腾了一天才从《jar调用dll文件提示找不到指定的模块Unable to load library》这篇博客找到解决办法,非常感谢写这篇博客的兄弟。

如果是原因3该如何解决?最简单的办法就是安装Visual Studio,勾选“使用C++的桌面开发”和“通用Windows平台开发”,然后安装,安装完成后就可以了(猜测:这两个模块中包含JNA所需要的环境)。详情请参考上文那个超链接。

解决问题的心路历程

一开始怀疑是让C++同事编译的dll文件有问题,所以自己下载mingw,用g++命令编译了一个,结果还是不行。

网上有人说Native.load方法使用相对路径的话要将dll文件放在System.getProperty("java.library.path")返回的路径下,比如jdk/bin或C:\Windows\System32,试了,没有用。

改用dll文件的绝对路径,还是报错。

又有博客说是jvm位数和编译dll文件环境的位数不一样,比如一个是64位,一个是32位,检查了下,不存在这个问题。

看了下源码,里面用到了jna.library.path,把dll文件放在自定义的myLibraryPath,然后将jna.library.path属性设置为myLibraryPath,还是不行。

System.setProperty("jna.library.path", myLibraryPath);

去github看jna的wiki,有一个官方的快速开始demo,是用jna调系统的clib,拿到本地运行一下,一切正常。

又怀疑是自己写的dll文件有问题,于是去github下载了一份jna调dll的demo,本地运行依然报这个错。

无奈,于是下载Dependency Walker查看dll文件的依赖关系,但是没看出所以然(当时已经有点浮躁,看不下去)。

这时已经很怀疑是自己的环境有问题,于是把从github下载的demo拿到同事电脑运行,也不行,报一样的错。

最后,同事发现了一篇博客(上文提到的那个),成功解决了我的问题,结论就是缺少库依赖。