2009-07-06 90 views
14

我正在通过JNI运行一个库(我没有写它),并在内部调用另一个DLL。除非我将另一个DLL的路径放在系统PATH变量(我在Windows XP上),否则会出现错误,提示“找不到相关库”。我希望能够在java命令行上处理这个问题,并且我已经尝试将它添加到-Djava.library.path和类路径中,两者都不起作用(我期望-Djava.library.path能够工作但没有classpath,但都没有工作)。有没有办法做到这一点?JNI依赖库

感谢,

杰夫

回答

18
  • 如果你有一个DLL名称 'MyNativeDLL.dll',那么你应该在你的LoadLibrary调用使用 'MyNativeDLL'。
  • 使用Dependency Walker,以检查是否存在由MyNativeDLL.dll
  • 如果有需要的任何文件,包括他们在同一文件夹中MyNativeDLL.dll - 一个你搞不定尝试将额外需要的文件在System32文件夹中。
+0

这将工作,但我想有依赖的DLL在任何他们想要的文件夹,然后只参考该文件夹。那可能吗? – 2009-07-06 14:09:33

5

我可以通过以反向依赖顺序在所有DLL上使用System.load(),而无需在PATH上放置任何DLL,以使其工作。为了清楚起见,我在所有依赖的DLL上调用System.load(),而不仅仅是JNI DLL。您不必在Windows附带的DLL上调用System.load()(它们位于PATH中)。

我在一个Web应用程序中这样做,其中一个jar包含了解压缩的DLL。你的情况似乎更简单,所以我认为它应该起作用。我通常遵循这里的解决方案:How to make a JAR file that includes DLL files?

0

我已经成功地使用JNA将文件夹注入到PATH变量中。如果您想要将您的依赖DLL部署在您的应用程序旁边,而不会污染全局环境或搞乱显式DLL加载顺序,则可以将其用作解决方法。

但是我不清楚类加载器的生命周期是如何影响这个的。我只在NetBeans模块系统下尝试过这种技术,但是如果通过ClassLoader类代码查看loadLibrary,您会看到它缓存了一些路径变量。可能也可能不需要创建一个新的类加载器来加载库。

缺点是您需要使用JNA或JNI。此外,它似乎是一个非常粗暴的破解。有关如何使用JNA设置环境变量的示例,请参见here

2

这对我有很大的帮助。 还管理加载的dll JNI使用内置的cygwin:

第一:

/* conditioned if OS is windows because also need it to work in Linux env. */ 
System.loadLibrary("cygwin1"); 

则:

System.loadLibrary("mylib"); 

在Windows上,这要求设置的java.library.path同时匹配库位置。

如果从Eclipse运行,此设置可能会被java构建路径中的“Native Libraries Location”(在JRE库设置中)替换。

但是,仍然觉得这有点棘手。