2010-09-09 163 views
0

我正在研究支持兩個通信接口的C#應用​​程序,每個通信接口都支持它自己的DLL。每個DLL包含相同的函數名稱,但其實現取決於支持的接口略有不同。實際上,用戶通常只在他們的機器上安裝一個DLL,而不是兩者。舊接口的DLL是這樣導入的:在運行時動態加載DLL

[DllImport("myOldDll.dll", 
      CharSet = CharSet.Auto, 
      CallingConvention = CallingConvention.StdCall)] 
public static extern int MyFunc1(void); 
public static extern int MyFunc2(void); 
public static extern int MyFunc3(void); 

這是試圖引入任一DLL的有效方法嗎?

[DllImport("myOldDll.dll", 
     CharSet = CharSet.Auto, 
     CallingConvention = CallingConvention.StdCall)] 
[DllImport("myNewDll.dll", 
     CharSet = CharSet.Auto, 
     CallingConvention = CallingConvention.StdCall)] 
public static extern int MyFunc1(void); 
public static extern int MyFunc2(void); 
public static extern int MyFunc3(void); 

理想情況下,我想這將是很好的檢測缺少DLL,如果先裝入嘗試失敗加載DLL第二。有沒有一種優雅的方式來做到這一點?

回答

0

如何做一個P/Invoke到`LoadLibrary'?

+0

然後你會使用獲得的句柄嗎? GetProcAddress和下一步是什麼? – 2010-09-09 19:53:30

+0

什麼都沒有。如果我得到了句柄,我會釋放它並通過使用該DLL名稱的extern進行調用。如果沒有,我會嘗試下一個DLL。 – 2010-09-09 19:58:57

0

在.NET 1.1中,您需要創建一個代理非託管DLL(將其寫入C或Delphi或...)並將其稱爲方法,而非託管DLL將完成剩下的工作。在.NET 2.0和更高版本中,您可以使用Assembly.LoadFile()和更多。不像你試圖使用的聲明那麼優雅,並且需要相當多的編碼。所以如果可能的話,我會建議一種代理方式。

0

也許你應該從DLL中導入不同名稱的方法,然後在你的程序中有一個委託,指向一個或另一個(無論哪個都合適),只調用委託。

+0

DLL沒有理由導出不同的名稱:您可以在引用上將它們別名。 – 2010-09-09 19:59:43

0

這聽起來像你最好的服務重新架構到模塊化插件風格的界面。

在網絡上有這樣一個十億半的例子,like this one。簡而言之,您在DLL的目錄上使用LoadAssembly(),然後轉回到您的通用基礎接口。