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

时间:2015-04-23 14:37:22

标签: java c++ dll java-native-interface dynamic-linking

说我有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的搜索?

ADD 1

似乎我从这里确认了2个级别的猜测:How to add native library to "java.library.path" with Eclipse launch (instead of overriding it)

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

ADD 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会如此不同。

2 个答案:

答案 0 :(得分:1)

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

2)系统文件夹通常是C:\ Windows \ System32(使用带有shgetspecialfolderpath() 的CSIDL_SYSTEM来获取给定系统上的rigth文件夹)

3)Windows文件夹(C:\ Windows)(带shgetspecialfolderpath()的CSIDL_WINDOWS以获取给定系统上的正确文件夹)

4)PAth environmnet变量

下列出的所有文件夹

答案 1 :(得分:0)

类似的链接:Must I place all dependent DLLs into the JDK's bin folder?

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

我开始怀疑我的用户%Path%可能太长。所以我将包含我的依赖DLL的文件夹路径从User%PATH%的 end 移动到开头。它现在有效!

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

但是我编写了另一个具有类似DLL依赖关系的Windows应用程序来确认我的猜测。该应用程序工作正常!所以我必须回顾一下我的结论。

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

  

我在User%PATH%中有一个C:\MinGW\bin条目,恰好包含一个   libstdc++-6.dll (977KB)但不幸的是,这是不兼容的   与我需要的(825KB)。它只适用于我在MinGW之前放置我的文件夹。

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