2009-04-23 129 views
1

我有第三方DLL需要使用LoadLibrary()動態加載,並使用__cdecl調用約定。我需要能夠使用VB6的DLL,所以我創建了一個我自己的包裝器DLL,它使用__stdcall調用約定並導出所需的函數。包裝第三方DLL

現在已經有了一個額外的要求,我正在努力看到如何管理;包裝的DLL爲另一個應用程序提供了一個API,並且我需要同時連接到應用程序的兩個實例。這是一個問題,因爲DLL沒有會話的概念,一個典型的互動會喜歡這樣:

tpc_connect("service1") 
// Do some stuff 
tpc_disconnect() 

,什麼我需要能夠做的是

session1 = tpc_connect("service1") 
session2 = tpc_connect("service2") 
// Do some stuff with session1 
// Do some stuff with session2 
tpc_disconnect(session1) 
tpc_disconnect(session2) 

主要問題,我發現一個進程只能被綁定到一個服務,所以我嘗試的第一個解決方案是通過使用ATL創建一個Out-Of-Process COM服務器來將DLL包裝移出到單獨的進程。我現在遇到的問題是我只能得到一個COM服務器的單個實例。

所以我的問題(最後)是有沒有辦法強制創建一個ATL COM服務器的新實例?這是解決問題的最佳方法,還是有人可以想出更好的方法來解決這個問題。

感謝傑克遜

回答

5

我建議你轉儲COM服務器的想法,並去與原始DLL的副本。我自己使用這種方法來獲得多個不是線程安全並且不支持多個實例的庫實例。

由於文件不同,Windows會將它們全部加載到單獨的地址空間中,從而使它們保持分離狀態。

這是我做過什麼:

  • 添加功能,包裝上,以創建和銷燬該庫的實例。

  • 更改所有其他函數以將指針指向正在使用的庫實例。

  • 在創建實例函數中,首先嚐試使用隨機文件名(即使用CreateHardLink)與原始DLL建立硬鏈接。如果失敗,則使用隨機名稱制作DLL的真實副本。如果您不想使用DLL擴展名,則不需要。動態加載DLL和函數指針的副本,並返回指向內部結構的指針。

  • 在destroy函數中,只需卸載DLL並將其刪除即可。

  • 最好在臨時目錄中創建副本,以便在發生崩潰時可以將其刪除,儘管我不確定Vista中是否存在限制,以及稍後從臨時目錄加載DLL 。

這一切都適合我。

+0

完成實現包裝 - 我嘗試使用CreateHardLink而不是一個副本,但它沒有爲我工作,所以最後與完整的副本的DLL。 – Jackson 2009-04-24 15:41:54

1

如果你只需要2節您可以使原始的dll文件的副本,並將其命名爲別的東西。他們在你的包裝DLL導出兩個單獨的調用(每個DLL一個)。 所以你必須:

session1 = tcp_connect("whatever")  'this points to dll1.dll 
session2 = tcp_connect2("whatever")  'this points to a copy of dll1 called dll2.dll 

這可能取決於其他應用的具體工作。無論如何都值得一試。

-don