最近做一個動態加載插件的項目,插件中的dll 主要是各廠商各型號的讀卡器的通用類庫,stdapi.dll,WltRS.dll,有的還有進一步封裝的dll,主要是為了簡化通用類庫的操作。
這些類庫都是用C語言,或者C++來編寫的,我的項目是用C#語言編寫,通過Dllimport來調用這些非托管dll的方法。
在做這個項目的時候,由于之前的讀卡器類庫都是通用的,所以即時使用兩款或者更多款讀卡器設備,加載的都是同一類dll,不會出現問題。
但是在開發與通用類庫不兼容的插件的時候(都是讀卡器插件),問題出現了。
一:輸入用戶名,密碼,登陸系統。
?1:該用戶能使用的設備如果都是調用通用類庫的讀卡器,那么使用起來沒有問題;
?2:該用戶能使用的設備只要有一款與其他的不同,那么在切換的時候問題就出現了。
什么問題呢?
假如現在有兩個設備,A和B,A屬于可以調用通用類庫的設備,B不能調用通用類庫,但是有自己的一套單獨的類庫。
當我啟用A設備的時候,第一次執行DllImport(“sdtapi.dll”)或者DllImport(“WltRS.dll”)后,那么這兩個dll就會加載到內存中。
這個時候我把A設備禁用,啟用B設備,B設備也有這樣的調用語句,DllImport(“sdtapi.dll”)或者DllImport(“WltRS.dll”),但是B設備的這兩個dll與A設備的不同,
大家猜猜看,這個時候B設備調用的是哪一個dll??
一開始,我以為B設備調用的是自己目錄下的dll。但是經過多次試驗,我發現我錯了。
只要是同名的dll,如果不指定絕對路徑方式進行加載,那么第一次加載之后的所有調用語句都是調用的第一次加載的那個dll中的方法。
所以就造成了設備使用的紊亂。但是如果這樣 DllImport(“sdtapi.dll”)或者DllImport(“WltRS.dll”),和DllImport(“C:\\sdtapi.dll”)或者DllImport(“C:\\WltRS.dll”),
調用的卻不是同一個dll,操作系統就會分別調用。我們的程序不能這樣寫,不然對用戶的約束性就太大了。。
針對這個問題,我的解決辦法是,將各個插件目錄下的文件重新命名,然后將代碼中的Dllimport中的代碼改成一致的名字,就OK了。
?