首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用loadLibrary加载dll

使用loadLibrary加载dll
EN

Stack Overflow用户
提问于 2015-05-04 15:21:32
回答 1查看 3.6K关注 0票数 1

我目前正在维护一个Java通信库,它封装了一些dll通过JNI提供的功能。在某种程度上,在Java中,我需要加载JNI包装器来转发我的请求,并最终调用本机库。目前,这是通过调用

代码语言:javascript
复制
System.loadLibrary("MyLibrary");

正如所述的这里,如果MyLibrary放在java.library.path中的某个地方,则应该始终找到它。目前,我的java.library.path似乎包括一些特定于Java的文件夹以及%PATH%环境变量中指定的所有目录:

代码语言:javascript
复制
C:\Program Files\Java\jdk1.8.0_45\bin;
C:\Windows\Sun\Java\bin;
C:\Windows\system32;
C:\Windows;
C:\Program Files\ImageMagick-6.9.0-Q16; 
C:\ProgramData\Oracle\Java\javapath;   
C:\Windows\system32;
C:\Windows;
C:\Windows\System32\Wbem;
C:\Windows\System32\WindowsPowerShell\v1.0\;
C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;
C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;
C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.0\;
C:\texlive\2014\bin\win32;
C:\MyFolder\Common32;
C:\MyFolder\Common64;
C:\Program Files (x86)\Microsoft Team Foundation Server 2012 Power Tools\;
C:\Program Files (x86)\Microsoft Team Foundation Server 2012 Power Tools\Best Practices Analyzer\;.

我现在的问题是,即使MyLibrary放在C:\MyFolder\Common64;中,上面的loadLibrary调用会产生一个UnsatisfiedLinkError,我似乎不明白为什么。但是,当我将它放入System32文件夹时,或者如果我在绝对指定路径的同时调用load,则会发现:

代码语言:javascript
复制
System.load("C:\\MyFolder\\Common64\\MyLibrary.dll");

我试图在运行时使用给出的java.library.path这里的答案中所建议的sys_path技巧来处理这里。以下工作完美无缺:

代码语言:javascript
复制
System.setProperty("java.library.path", "C:\\MyFolder\\Common64\\" );

Field fieldSysPath = ClassLoader.class.getDeclaredField( "sys_paths" );
fieldSysPath.setAccessible( true );
fieldSysPath.set( null, null ); 

System.loadLibrary("MyLibrary");

因此,如果我用自定义路径替换整个java.library.path属性,则dll将成功加载。但是,这不是所需的行为,因为我希望通过向%PATH%添加正确的目录来动态查找dll。此外,将我的自定义路径添加到java.library.path,如下所示

代码语言:javascript
复制
String curJavaLibraryPath = System.getProperty("java.library.path");
System.setProperty("java.library.path", curJavaLibraryPath + ";C:\\MyFolder\\Common64\\" );     

也不管用。

目前,我正试图在Win7 64位机器上实现这一功能。如果相关的话,我的dll也被编译为x64。

当我以x86模式编译我的Java库并将相应的JNI复制到C:\MyFolder\Common32\并将该目录添加到%PATH%时,一般过程工作得非常完美。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-28 10:17:42

显然,loadLibrary()文档已经成功地欺骗了我。在UnsatisfiedLinkError的情况下,它声明

UnsatisfiedLinkError -如果库不存在。

因此,我显然认为loadLibrary()在任何时候都不能看到我指定的库。然而,情况并非如此,因为此异常也可能意味着它发现了错误(与VM不兼容)位数中的对应库。

据我所知,您唯一能做的检查就是分析异常所包含的错误消息,以确定您到底拥有哪个UnsatisfiedLinkError。我最后所做的就是:

代码语言:javascript
复制
try
{
    System.setProperty(JAVA_LIBPATH_PROPNAME, libpath);  
    ForceReloadLibraryPath();
    System.loadLibrary("AdsToJava");        
}
catch (UnsatisfiedLinkError ex)
{
    // We simply did not find the dll
    if (ex.getMessage().equals("no MyLibrary in java.library.path")) {

        // Just alert that nothing was found

    } else if ( (ex.getMessage().endsWith("Can't load IA 32-bit .dll on a AMD 64-bit platform")) || 
                (ex.getMessage().endsWith("Can't load AMD 64-bit .dll on a IA 32-bit platform")) ) {

        // Extract the path at which the dll whith the wrong bitness was found 
        // and remove it from the search path and try again
    }
}

显然,在调用loadLibrary之前,您也可以预先检查搜索路径,但由于这种方法也适用于用户复制dll的情况,所以我认为这是最强大的选项。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30033785

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档