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

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

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

下面的文件夹布局可行吗?

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

我的猜测是,有 2 级 依赖项解析。

[1 级]:

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

[2 级]:

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

这是正确的吗?

如果我把%_JAVA_OPTIONS%设为-Djava.library.path=MainFolder\SubFolder,我觉得可以覆盖对JNI.dll的搜索。 但是它也会涵盖对 native.dll 的搜索吗?

添加 1

看来我对 2 级的猜测从这里得到了证实:How to add native library to "java.library.path" with Eclipse launch (instead of overriding it)

请参阅 kevin cline 的评论。但是提到的带有 LD_LIBRARY_PATH 环境变量的解决方案仅适用于 Linux.

添加 2

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

我的困惑是:JNI.dll 取决于 native.dll两者 main.exe的当前工作目录中。实际上它们在 CWD 的子文件夹中。

如果我直接运行main.exe,我只需要设置java.library.path = <other path>\MainFolder\SubFolder。两个 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环境变量下列出的所有文件夹

类似的link:

受此主题启发:System versus user PATH environmental variable...winmerge works only if I add the path to the user PATH

我开始怀疑我的用户 %Path% 是否 太长。因此,我将包含依赖 DLL 的文件夹路径从用户 %PATH% 的 end 移动到 beginning。现在可以用了!

首先,我得出结论,实施 Windows' DLL 查找算法的人存在一些截断问题。我 几乎 认为它是另一个烦人的 Windows 错误。

但我写了另一个 Windows 应用程序,它具有类似的 DLL 依赖关系来证实我的猜测。该应用程序工作正常!所以我必须重新审视我的结论。

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

I have a C:\MinGW\bin entry in User %PATH%, which happens to contain a libstdc++-6.dll (977KB) but unfortunately, which isn't compatible with the one I need (825KB). It only works if I place my folder before MinGW.

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