JNA:本地库依赖和JAR提取

4
我将通过JNA访问MSP430.dll(参见此处)。但是该库有一个依赖于其他本地库的问题,这些库与MSP430.dll捆绑在一起。这个被依赖的本地库叫做HIL.dll。使用jna.library.path可以完美地解决这个问题。现在,我想将本地库捆绑到我的.jar包中。然后,我想使用JNA框架的自动本地库加载。但这会导致依赖关系的本地库出现问题。如果我将MSP430.dll和HIL.dll打包到我的.jar包中,那么我就会得到以下错误:“JNA java.lang.UnsatisfiedLinkError和指定的模块无法找到”。这意味着无法解决MSP430.dll对HIL.dll的依赖关系。在JNA的调试输出中,我只能看到从.jar包中提取MSP430.dll。在这种情况下,错误是可以理解的。在下一个尝试中,我显式加载HIL.dll,我可以看到HIL.dll然后是MSP430.dll的提取。但我仍然从JNA中得到模块错误。

我查看了JNA提取方法的代码。我发现JNA会将本地库提取到系统临时目录并在其中创建自己的临时目录。但现在我认为问题在于,JNA为本地库创建了以“jna”为前缀和唯一生成的数字值的临时文件。以下是JNA的输出:

Found library 'HIL.dll' at C:\Users\RD3\AppData\Local\Temp\jna-80961\jna1305152974718331988.dll

我认为MSP430.dll需要使用未重命名的HIL.dll来找到它。我已经测试过直接加载HIL.dll,以下是在应用程序中作为第一个调用的代码:
System.loadLibrary(C:\\absolutepath\\HIL.dll);

然后,通过JNA仅从.jar包加载MSP430.dll,这样就可以无问题地进行操作。之后,我将HIL.dll重命名为lol.dll,并使用以下调用:

System.loadLibrary(C:\\absolutepath\\lol.dll);

然后我再次收到来自JNA的模块错误。MSP430.dll无法解析重命名的HIL.dll。

是否有可能将具有依赖关系的本地库打包到.jar包中,并使用JNA进行加载?

这是使用JNA显式加载HIL.dll的JNA调试输出:

C:\Users\RD3\Desktop>call "C:\Program Files (x86)\Java\jre1.8.0_25\bin\java.exe"
 -Djna.debug_load=true -jar C:\Data\Workspace\NetBeans\MspApiTest\target\MspApiTest-1.0.0-SNAPSHOT-jar-with-dependencies.jar
Looking in classpath from sun.misc.Launcher$AppClassLoader@1f96302 for /com/sun/jna/win32-x86/jnidispatch.dll
Found library resource at jar:file:/C:/Data/mstandfuss/Workspace/NetBeans/MspApiTest/target/MspApiTest-1.0.0-SNAPSHOT-jar-with-dependencies.jar!/com/sun/jna/win32-x86/jnidispatch.dll
Looking for library 'HIL.dll'
Adding paths from jna.library.path: null
Trying HIL.dll
Adding system paths: []
Trying HIL.dll
Looking for lib- prefix
Trying libHIL.dll
Looking in classpath from sun.misc.Launcher$AppClassLoader@1f96302 for HIL.dll
Found library resource at jar:file:/C:/Data/mstandfuss/Workspace/NetBeans/MspApiTest/target/MspApiTest-1.0.0-SNAPSHOT-jar-with-dependencies.jar!/win32-x86/HIL.dll
Found library 'HIL.dll' at C:\Users\RD3\AppData\Local\Temp\jna-80961\jna1305152974718331988.dll
Looking for library 'MSP430.dll'
Adding paths from jna.library.path: null
Trying MSP430.dll
Adding system paths: []
Trying MSP430.dll
Looking for lib- prefix
Trying libMSP430.dll
Looking in classpath from sun.misc.Launcher$AppClassLoader@1f96302 for MSP430.dll
Found library resource at jar:file:/C:/Data/mstandfuss/Workspace/NetBeans/MspApi
Test/target/MspApiTest-1.0.0-SNAPSHOT-jar-with-dependencies.jar!/win32-x86/MSP430.dll
Exception in thread "main" java.lang.UnsatisfiedLinkError: Das angegebene Modul wurde nicht gefunden.

        at com.sun.jna.Native.open(Native Method)
        at com.sun.jna.Native.open(Native.java:1759)
        at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:260)
        at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:398)
        at com.sun.jna.Library$Handler.<init>(Library.java:147)
        at com.sun.jna.Native.loadLibrary(Native.java:412)
        at com.sun.jna.Native.loadLibrary(Native.java:391)
        at de.sitec.jmspflash.Msp430Native.<clinit>(Msp430Native.java:22)
        at de.sitec.jmspflash.Msp430Impl.init(Msp430Impl.java:50)
        at de.sitec.jmspflash.Msp430Impl.createMsp430Impl(Msp430Impl.java:36)
        at de.sitec.mspapitest.App.main(App.java:34)

C:\Users\RD3\Desktop>

最好的问候

1个回答

3
假设你遇到的唯一问题是依赖库的名称,请参考Native.extractFromResourcePath()。你可以使用它来提取非显式依赖项,并使用File.rename()确保库的名称符合您的要求。

1
我遇到了完全相同的问题,这个建议对我很有用。 - Martynas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接