如何让 JNA 从一个 jar 文件中提取多个 DLL 文件?

How to get JNA to extract several DLL files from a jar file?

我正在使用 JNA 在 NetBeans 中开发一个 Java 项目。根据 JNA documentation,我可以将我的 DLL:s 放入 jar 以供 Java 使用:

Make your native library available on your classpath, under the path {OS}-{ARCH}/{LIBRARY}, where {OS}-{ARCH} is JNA's canonical prefix for native libraries (e.g. win32-x86, linux-amd64, or darwin). If the resource is within a jar file it will be automatically extracted when loaded.

这就是我想要做的,所以我在src/win32-x86-64下的项目中包含了DLL:s。如果我用 netbeans 构建一个 jar 文件,然后将 jar 文件包含在另一个项目中,一切正常,JNA 可以毫无问题地找到我的库。这是我在 jna.debug_load on:

上得到的结果
Looking in classpath from sun.misc.Launcher$AppClassLoader@15db9742 for /com/sun/jna/win32-x86-64/jnidispatch.dll
Found library resource at jar:file:/C:/MyNetBeansProject/dist/lib/jna-4.2.2.jar!/com/sun/jna/win32-x86-64/jnidispatch.dll
Looking for library 'MyLibrary'
Adding paths from jna.library.path: null
Trying MyLibrary.dll
Adding system paths: []
Trying MyLibrary.dll
Looking for lib- prefix
Trying libMyLibrary.dll
Looking in classpath from sun.misc.Launcher$AppClassLoader@15db9742 for MyLibrary
Found library resource at file:/C:/MyNetBeansProject/build/classes/win32-x86-64/MyLibrary.dll
Looking in C:/MyNetBeansProject/build\classes\win32-x86-64\MyLibrary.dll
Found library 'MyLibrary' at C:/MyNetBeansProject/build\classes\win32-x86-64\MyLibrary.dll

显然没有使用 jar 中的 DLL。而是使用构建文件夹中的 DLL。

现在,如果我将 jar 文件移动到另一个文件夹并将其包含在我的项目中,我会得到 UnsatisfiedLinkError。 JNA 给出以下输出:

Looking in classpath from sun.misc.Launcher$AppClassLoader@70dea4e for /com/sun/jna/win32-x86-64/jnidispatch.dll
Found library resource at jar:file:/C:/SomeFolder/lib/jna-4.2.2.jar!/com/sun/jna/win32-x86-64/jnidispatch.dll
Looking for library 'MyLibrary'
Adding paths from jna.library.path: null
Trying MyLibrary.dll
Adding system paths: []
Trying MyLibrary.dll
Looking for lib- prefix
Trying libMyLibrary.dll
Looking in classpath from sun.misc.Launcher$AppClassLoader@70dea4e for MyLibrary
Found library resource at jar:file:/C:/SomeFolder/MyNetBeansProject.jar!/win32-x86-64/MyLibrary.dll

看起来 JNA 在 jar 中找到了 DLL,但它没有尝试提取它。我在我的临时文件夹中找不到它(JNA 在其中提取它自己的内部 DLL)。

这里有什么问题?为什么 JNA 不提取文件?我该如何解决这个问题?

(我不知道这是否相关,但我应该提到我的 DLL 依赖于 jar 中同一文件夹中的多个其他 DLL 文件。不确定 JNA 是否会为我自动提取它们,但到目前为止,JNA 似乎甚至没有提取我实际使用的 DLL。)

编辑: 定位 jnidispatch.dll 似乎没有问题。根据 jna.debug_load.jna 设置为 true 时的输出,文件在 JAR 中找到并解压缩到临时文件夹。

JNA 在无法加载 dll 时显示错误 "UnsatisfiedLinkError"。如果您的 DLL 需要系统路径中不存在的另一个自定义 DLL,它将失败,因为 JNA 不会自动提取此 dll。

JNA 作为一个 Java 库不知道系统库的依赖关系,所以它不能从 jar 中提取。 解决方案是在 JNA Java 接口中指定所有依赖项。

你可以在这里看到一个例子


操作系统幕后发生的事情

最后,操作系统根据主要可执行文件的请求加载库。在这种情况下,主要可执行文件是 java.exe 或 (jvm.dll)。如果系统在失败的路径中找不到库,并且 java 生成异常。

另一个相关且已解决的问题是