JNI DLL如何搜索其依赖的本机DLL

How does a JNI DLL search for its dependent native DLL?

本文关键字:DLL 依赖 本机 何搜索 JNI 搜索      更新时间:2023-10-16

假设我有JNI.dll。这取决于native.dll。现在我的Java应用程序调用System.loadLibrary("JNI")

以下文件夹布局是否有效?

MainFolder
|--main.exe
|--SubFolder
|--JNI.dll
|--native.dll

我的猜测是,依赖性解析有两个级别。

【1级】:

System.loadLibrary("JNI")使用JVM属性java.library.path来定位JNI.dll

【2级】:

JNI.dll依赖于Windows系统机制来定位native.dll

这是正确的吗?

如果我将%_JAVA_OPTIONS%设置为-Djava.library.path=MainFolderSubFolder,我认为它可以覆盖对JNI.dll的搜索但它也会覆盖对native.dll的搜索吗

添加1

我对两个层次的猜测似乎从这里得到了证实:如何将原生库添加到"java.library.path";Eclipse启动(而不是覆盖它)

参见凯文·克林的评论。但上述带有LD_LIBRARY_PATH环境变量的解决方案仅适用于Linux。

添加2

我想我没有把问题说清楚。让我这样说吧。

我的困惑是:JNI.dll依赖于native.dll这两个而不是main.exe的当前工作目录中。实际上,它们在CWD的一个子文件夹中。

如果我直接运行main.exe,我只需要设置java.library.path = <other path>MainFolderSubFolder。两个DLL都已正确找到。

但是,如果我从Eclipse运行我的项目,除了设置java.library.path之外,我还必须将"\MainFolder\SubFolder"放在%PATH%环境变量中。

我只是不知道为什么Eclipse如此不同。

1)它在当前目录中搜索。

2) 系统文件夹通常为C:\Windows\System32(使用CSIDL_System和shgetspecialfolderpath()在给定系统上获得正确的文件夹)

3) Windows文件夹(C:\Windows)(CSIDL_Windows与shgetspecialfolderpath()在给定系统上获得正确的文件夹)

4) PAth环境变量下列出的所有文件夹

类似的链接:我必须将所有依赖的DLL放入JDK';s的bin文件夹?

受此线程启发:系统与用户PATH环境变量。。。winmerge只有在我将路径添加到用户path 时才有效

我开始怀疑我的用户%Path%是否太长。因此,我将包含我的依赖DLL的文件夹路径从用户%path%的结尾移动到开头。它现在起作用了!

首先,我得出结论,一个实现Windows DLL查找算法的人有一些截断问题。我几乎认为这是另一个烦人的Windows Bug。

但我写了另一个Windows应用程序,它有类似的DLL依赖项来证实我的猜测。该应用程序运行良好!所以我必须重新审视我的结论。

我逐一检查了"用户%PATH%"条目,并将文件夹放在每个可能的位置。最后,我找到了的根本原因

我在用户%PATH%中有一个C:MinGWbin条目,它恰好包含libstdc++-6.dll (977KB),但不幸的是,它不兼容和我需要的CCD_ 24。只有当我把文件夹放在MinGW之前时,它才有效。

现在这个问题似乎得到了解决。但另一个问题出现了,如果我想同时使用我的DLL和MinGW,我需要来回切换吗?