java如何加載本地的dll文件


首先,應當明確,dll有兩類:(1)Java所依賴的dll和,(2)dll所依賴的dll。正是由於第(2)種dll的存在,才導致了java中加載dll的復雜性大大增加,許多說法都是這樣的,但我實驗的結果卻表明似乎沒有那么復雜,后面會予以詳細闡述。 

其次,Java中加載dll的方式也有兩種:(1)通過調用System.loadLibrary(String filename)和,(2)通過調用System.load(String filename)方法。其底層都是通過使用ClassLoader中的loadLibrary(Class fromClass, String name, boolean isAbsolute)方法來實現的,區別僅在於(1)中的filename必須是絕對路徑,(2)中的filename只能是dll名,不允許包含文件夾。 

再者,Eclipse是一個相當強大的平台,其提供的BundleClassLoader的強大是一個很重要的原因,對於dll的加載也有自己一套很別致的做法,值得我們采納。 


根據上面的介紹,分兩部分闡述Java中加載dll面臨的主要問題和解決途徑。 

1. 在一般Java程序中加載dll 

我所做的工作,需要加載的dll如下: 

DigitDll.dll 
DsivsAcct.dll 
DsivsComm.dll 
DsivsTrans.dll 
JBPack.dll 
XCodeDll.dll 
ImageDllCtrl.dll 
yhfiche.dll 
yhocr.dll 
yhbill.dll 
TSealSvrDll.dll 
TImg.dll 
TImage.dll 

直接調用的是TImage中的若干方法,列表中TImage之前的所有其直接或間接依賴的,不僅要把所有的dll load全,更要注意他們之間的依賴關系,被依賴dll一定要先加載,否則就會報錯:UnsatisfiedLinkError。故而,首先應理清dll 之間的依賴關系,上面的列表已經是處理過的了。 

接下來是設置JVM的搜索路徑,使其能夠找到你的dll。JVM的搜索路徑由java.library.path系統屬性決定,其默認值為系統環境變量中的PATH 內容。因此,可以通過修改PATH變量來達到設置java.library.path屬性的目的(改變之后Eclipse需要重新啟動),一般的方法是在 PATH中加入dll所在文件夾的絕對路徑。另一種方法是在Java命令的參數中加入“-Djava.library.path=dll所在文件夾的絕對路徑”來設置(可以用;分開多個路徑)。對於Eclipse開發環境上的應用程序,可以通過修改其啟動參數,在VM arguments編輯框中加入前述參數。對於打包出來的Eclipse安裝包,可編輯其啟動目錄下的application.ini(假設其啟動文件為 application.exe),在-vmargs后加入前述參數來設置java.library.path的值。需要注意的是,一旦JVM已經啟動,則無法再修改java.library.path的內容了,也就是說,通過: 

System.setProperty("java.library.path", "c:\mylib"); 

這樣的方式是無法達到目的的,因為該屬性是只讀的。Sun公司的論壇上曾經討論過如何在代碼中修改java.library.path的問題,結論是:不能通過代碼修改!如果嫌"java -Djava.library.path=c:\mylib"這樣的方式寫得太死,也只能是通過shell編程之類的方法對路徑進行預處理,以改善其靈活性了。 

如果你的dll是封裝在jar包中的,則需要首先將之解壓縮到一個臨時路徑上,然后再將該路徑加入到Djava.library.path中,或者干脆將其解壓縮到系統路徑上。 

2. 在Eclipse平台上加載dll 

上面提到,Java中對本地庫路徑的設置方式做得太死,這也是我自己的切身體會,但令人感到欣慰的是我們的Eclipse平台的提供了一套比較靈活的做法,通過eclipse提供的BundleClassLoader,你可以將dll封在plugin中,既不需要在使用時解壓縮,也不需要額外設置 java.library.path屬性,BundleClassLoader會自行到以相對plugin根目錄的指定目錄下去查找你的dll,這些目錄是:ws/win32/, os/win32/x86/, os/win32/, nl/zh/CN/, nl/zh/,見org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader和 org.eclipse.core.runtime.internal.adaptor.EclipseClassLoadingHook。 

我的目錄設置是: 
.classpath 
.cvsignore 
.project 
build.properties 
classes 
CVS 
lib 
META-INF 
os 
plugin.xml 
src 

我把所有的dll都放到了os下面的win32目錄內,同樣可以建立ws/win32等目錄用於放置本地庫。如此處理之后,不用再修改任何系統變量就可以順利加載本地庫了。 

另外,Eclipse還在MANIFEST文件中提供了Bundle-NativeCode的設置項,也是用於加載本地庫的,有待進一步研究 

本文匆匆而就,希望對自己對大家都能有所幫助 


免責聲明!

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



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