【问题标题】:What becomes the search path of a .dll loaded with System.loadLibrary() in java?java 中使用 System.loadLibrary() 加载的 .dll 的搜索路径是什么?
【发布时间】:2015-09-09 09:28:01
【问题描述】:

我有一个系统,我有 1 个 .exe 文件、4 个 .dll 文件和一个 jar 文件,其中的依赖关系如下所示:

A.exe -> 调用 -> B.dll -> 通过JNI调用 -> C.jar -> 使用 System.loadLibrary("") 加载 -> D.dll -> 调用 E.dll

现在,BE 是一个模块,所有这些文件都在同一个目录中。 A.exe 是放置在不同目录中的应用程序,可以使用其中的多个模块。

我的主要问题是,当 D.dll 尝试加载 E.dll 时,我得到一个“找不到依赖库”的 java.lang。不满意的链接错误。如果我站在模块目录中并手动运行 C.jar 则没有此类错误并且 D.dll 设法加载 E.dll很好。

所以,我的主要问题是:AddDllDirectory(%moduleDir%)A.exe 中运行,但它实际上“继承”了多远? C.jar 是否会以某种方式删除此函数添加的目录?有没有办法在 System.loadLibrary("") 调用之前从 java 扩展 dll 搜索路径,以便加载的 .dll 继承此搜索路径?

  1. java.library.path设置为B.dll通过JNI启动JVM时的模块目录
  2. 我想避免 A.exe 更改 PATH 环境变量
  3. D.dllE.dll 无需更改

提前感谢您的任何回答

【问题讨论】:

  • 当您的系统库D.dll 尝试加载系统库E.dll 时,为什么会出现Java 异常java.lang.UnsatisfiedLinkError。异常消息的措辞是什么?是D.dll: %1 is not a valid Win32 application 还是no D in java.library.path
  • 这是错误消息:java.lang.UnsatisfiedLinkError: <moduleDir>\D.dll: Can't find dependent libraries 这里发生的情况是,在 java 中,当 System.loadLibrary("D.dll") 执行时,它会失败,因为它找不到 E.dll 其中 D.dll 依赖于

标签: java c++ dll java-native-interface loadlibrary


【解决方案1】:

这里是对您的案例中发生的错误的简短说明。

假设如下

  • Java 调用 System.loadLibrary("D"); 类在目录 APP_DIR 中
  • D.dll 依赖于E.dll,两者都在 DLL_DIR 目录中

案例 1 java.library.path 未指定

no D in java.library.path

案例2 -Djava.library.path=%DLL_DIR%

D.dll: Can't find dependent libraries

因为 Java 会检查 D.dll 中是否存在 %DLL_DIR% 加载库(使用 Windows LoadLibrary 功能)。 Windows 会尝试查找在 PATH 和当前目录中未找到的依赖 E.dll

案例 3 -Djava.library.path=%DLL_DIR%set PATH=%DLL_DIR%;%PATH%

System.loadLibrary("D"); will be successful

有关此主题的一些附加链接

【讨论】:

  • 从您的最后一个链接中阅读以下内容后:SetDllDirectory("") also affects how child processes loads their DLLs. Good news: It does not affect dynamic linking... Bad news: It affects implicit linking... 这是否意味着如果D.dll 使用动态链接加载E.dll,则忽略A.exe 中调用的AddDllDirectory() 函数,而如果D.dll 静态加载 E.dll 不是吗?
  • @MartinRindarøy 我自己无法证明(从未从库中调用过 Java 代码)。但对我来说,中断是在你调用 JVM 的时候,因为库解析在这里的工作方式不同。所以子D.dll 不会继承A.exe 的设置。也许您可以在 Java 代码中将当前目录更改为 C.jar 的位置,然后 Windows 中的 LoadLibrary 会在当前目录中找到 C.dll。最好是为此创建一个小测试用例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-11
  • 1970-01-01
  • 2011-01-20
  • 1970-01-01
相关资源
最近更新 更多