2011-07-26 46 views
9

我用下面的代碼在JNA加載DLL(不相關的代碼被省略了):JNA UnsatisfiedLinkError,但jna.library.path設置

public class JNAMain { 
     public interface PointShapeBuffer extends Library { ... } 

     public static void main(String[] args){ 
      System.setProperty("jna.library.path", "c:\\jnadll"); 
      System.setProperty("java.library.path", "c:\\jnadll"); 

      PointShapeBuffer jna = (PointShapeBuffer) Native.loadLibrary("FileGDBAPI", PointShapeBuffer.class); 
     } 
    } 

而且我得到以下錯誤:

Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'FileGDBAPI': The specified module could not be found. 

我也試過設置虛擬機參數。任何建議都會很棒。

編輯:作爲參考,我使用的是公開發布的圖書館here(需要註冊)。

+0

WIndows?萊納斯? PATH設置爲在Windows上包含共享庫? Linux上的LD_LIBRARY_PATH? – bmargulies

+0

這是Windows 7. PATH環境變量已更改爲包含「C:\ jnadll」,但我仍然收到錯誤。 – Dave86

+0

這裏同樣的問題。我可以加載user32.dll就好了,但它試圖加載任何非Windows 32位DLL,無論我把它們放在哪裏/如何指向它們的路徑,它都會嘔吐。 –

回答

2

您需要指定包含您的DLL的文件夾,而不是DLL的實際路徑。

例如對於baz.dllc:\foo\bar\baz.dll,路徑應設置爲c:\\foo\\bar。 (請注意,如果您使用的是退格,您必須用反斜槓將它們轉義出來)

+0

對不起,抽象出文件路徑 - 我不想在工作機器上放棄任何敏感的東西。該DLL現在位於C:\ jnadll \ FileGDBAPI.dll中,但將路徑設置爲「c:\\ jnadll」仍然不行。 – Dave86

+1

@Dave:你有沒有試過在程序調用期間設置系統屬性,而不是在main? ('-Djna.library.path = c:\ jnadll') –

+0

不幸的是,也沒有工作。我用Dependency Walker來查看是否有任何缺失的引用,並向我拋出這個錯誤:「找到了具有不同CPU類型的模塊。」這是針對64位的gpsvc.dll和sysntfy.dll。我無法找到32位版本,所以我再次陷入困境。 – Dave86

1

您可能需要使用jna.jar和platform.jar下載最新版本,幷包含這些內容。那麼不需要設置路徑。

8

根據我的經驗,當64位Win7上的64位jvm調用32位本地dll時,您通常會看到此錯誤。對於64位和32位應用程序,Win7的工作方式不同。

在64位Win7上,您可以調用本機32位dll的函數,但是您需要使用32位JVM。

  1. 下載並安裝32位Java運行時環境(JRE)。您可以在同一臺機器上安裝32位和64位jvm,只要確保它們安裝在單獨的目錄中即可。
  2. 確保在執行程序時運行32位JRE而不是默認的64位JVM。 A)更改您的CLASSPATH和JAVA_HOME環境變量以指向32位jvm,或者編寫一個腳本來設置CLASSPATH和JAVA_HOME並啓動您的應用程序。

原因是32位dll與64位應用程序不兼容,64位Win7使用32位模擬器運行32位應用程序。雖然Windows庫可能被命名爲xxxx32.dll(例如user32.dll),但是64位Win7上的System32文件夾中的庫是64位庫,而不是32位,而SysWOW64中的庫是32位庫,這會混淆正確嗎?

您也可以將庫放在32位系統文件夾(SysWOW64)中,並在32位JVM中進行JNI調用。

查看以下鏈接以獲取完整說明,瞭解64位Win7如何處理庫;

http://www.samlogic.net/articles/32-64-bit-windows-folder-x86-syswow64.htm

如果你真的想幫助自己入睡,試圖開始在此;)

http://msdn.microsoft.com/en-us/windows/hardware/gg463051.aspx

4

更改:

Native.loadLibrary("FileGDBAPI", PointShapeBuffer.class); 

到:

Native.loadLibrary("C:\\jnadll\\FileGDBAPI.dll", PointShapeBuffer.class); 

如果你潛入JNA源代碼的話,你會發現在NativeLibrary類一個可愛的小鉤:

/** Use standard library search paths to find the library. */ 
    private static String findLibraryPath(String libName, List searchPath) { 
     // 
     // If a full path to the library was specified, don't search for it 
     // 
     if (new File(libName).isAbsolute()) { 
      return libName; 
     } 
     ... 

因此,這將趕上,如果你只是傳遞一個絕對路徑,甚至不使用搜索路徑。這就是爲什麼你不必擔心jna.library.lib。

+0

這是我開始做的,沒有工作。 –

+0

不知道該怎麼告訴你..也許你有不同版本的JNA。這對我和其他人以及源代碼(從我的jna版本複製)不起作用。 – JHowIX

+1

原來,JNA並沒有區分*無法找到DLL *和*無法找到DLL依賴關係*。所以這個DLL是沒問題的,但是因爲我發現使用了依賴關係walker,所以失去了依賴關係。 –

-1

這可能是因爲lebweb套件中存在混淆。我不確定,但那必須是隻有現在你可以做一件事情來嘗試這件事。

$ dpkg -l | grep -i jna 

試試這個命令如果u得到這個輸出

ii libjna-java 3.2.7-4 Dynamic access of native libraries from Java without JNI 

或任何其他輸出,那麼這個u需要從系統中刪除,然後是JNA因爲如果程序本身有JNA罐子與再有對於同樣的系統jna是不需要的。所以做這樣的事情。

sudo apt-get autoremove libjna-java 

並嘗試再次重新啓動該應用程序。它會運行並且不運行,然後嘗試安裝新版本的libwebkit-gtk

希望這會有所幫助。這幫助了我。