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,是否需要来回切换?
假设我有 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 alibstdc++-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,是否需要来回切换?