在Jar包中打入DLL文件並調用的方式


在一些Java應用中需要實用JNI來調用DLL動態鏈接庫,但是,如果做成模塊打成JAR包,一般情況是無法直接載入DLL的。

常用的DLL載入方式如下

 

  1. //加載test.dll   
  2. System.loadLibrary("test");   
  3. System.load("test");  

 

需要說明的是加載DLL的有效路徑與一個JVM中的系統變量有關,可以用以下方法查看該變量。

 

  1. System.getProperty("java.library.path");  

 

在該變量中含有當前路徑".",需要特別說明,這個當前路徑是執行時的當前路徑,舉例來說。

 

  1. //當前路徑在C:根目錄下,而執行的程序在C:/app/Test.class   
  2. C:\> java app/Test //這時的 . 表示的是C:\   
  3. C:\app> java Test  //這時的 . 表示的是C:\app  

 

接下來就是重點了,DLL已經打包到了JAR中,比如打進了APP.jar,那對於Windows來說,這個DLL不存在於任何的目錄中,自然無法正常調用到。那解決方法就是在執行的時候將JAR包中的DLL解到某個地方,然后再載入。因為使用下面的代碼可以將JAR包中的任何文件作為資源載入。

 

  1. MyClass.class.getResourceAsStream(dllName);     MyClass.class.getResource(dllName);  

 

這樣就可以在JAR包執行時把DLL讀取出來解在一個地方了,我寫了一個方法來代替loadLibrary,DLL會被放入系統的臨時文件夾中,在那里會被載入,synchronized保證該過程在多線程下安全,也許在將來可以優化。

 

  1. //BIN_LIB為JAR包中存放DLL的路徑   
  2. //getResourceAsStream以JAR中根路徑為開始點   
  3. private synchronized static void loadLib(String libName) throws IOException {   
  4.     String systemType = System.getProperty("os.name");   
  5.     String libExtension = (systemType.toLowerCase().indexOf("win")!=-1) ? ".dll" : ".so";   
  6.        
  7.     String libFullName = libName + libExtension;   
  8.        
  9.     String nativeTempDir = System.getProperty("java.io.tmpdir");   
  10.        
  11.     InputStream in = null;   
  12.     BufferedInputStream reader = null;   
  13.     FileOutputStream writer = null;   
  14.        
  15.     File extractedLibFile = new File(nativeTempDir+File.separator+libFullName);   
  16.     if(!extractedLibFile.exists()){   
  17.         try {   
  18.             in = SMAgent.class.getResourceAsStream(BIN_LIB + libFullName);   
  19.             if(in==null)   
  20.                 in =  SMAgent.class.getResourceAsStream(libFullName);   
  21.             SMAgent.class.getResource(libFullName);   
  22.             reader = new BufferedInputStream(in);   
  23.             writer = new FileOutputStream(extractedLibFile);   
  24.                
  25.             byte[] buffer = new byte[1024];   
  26.                
  27.             while (reader.read(buffer) > 0){   
  28.                 writer.write(buffer);   
  29.                 buffer = new byte[1024];   
  30.             }   
  31.         } catch (IOException e){   
  32.             e.printStackTrace();   
  33.         } finally {   
  34.             if(in!=null)   
  35.                 in.close();   
  36.             if(writer!=null)   
  37.                 writer.close();   
  38.         }   
  39.     }   
  40.     System.load(extractedLibFile.toString());   
  41. }  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM