2009-07-06 89 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庫設置中)替換。

但是,仍然覺得這有點棘手。