2013-12-11 62 views
2

最初,通過後期綁定創建COM可能並不合適,然後通過InvokeMember調用其方法。 但是現在,也許爲時已晚從頭開始重做所有事情。傳遞COM接口時出錯

因此,告訴我該怎麼做。

有一個在DLL中的一個COM對象。用Delphi7編寫。

在C#中,它的使用方法如下:

Type comType = Type.GetTypeFromProgID(ProgID, false); 
object comObj = Activator.CreateInstance(comType); 
// and then call methods 
comType.InvokeMember("DoLongWork", BindingFlags.InvokeMethod, null, comObj, null); 

現在,我們需要給它添加機會調用服務器的方法(即誰保持對自己這個COM對象的一個​​)

爲此,在其TLB一個COM對象加入另外的接口

IHookCallback = interface(IDispatch) 
procedure ServerHook(DoStuff: integer); safecall; 
end; 

並且還在其主界面添加初始化方法回調

ITestDisp = dispinterface 
... 
procedure SetupHook(const Callback: IHookCallback); safecall; 

然後導入到VS項目的DLL - 這個COMOM裏面。從而獲得對接口描述的訪問。

然後(在VS)中創建實現該接口的類。 我嘗試它通過InvokeMember

comType.InvokeMember("SetupHook", BindingFlags.InvokeMethod, null, comObj, new object[] {SomeClass as IHookCallback}); 

轉移到COM等,也試圖

comType.InvokeMember("SetupHook", BindingFlags.InvokeMethod, null, comObj, new object[] {SomeClass}); 

我收到一個錯誤

Exception has been thrown by the target of an invocation. 

的InnerException

Specified cast is not valid. 

我哪裏錯了?

+0

我必須承認,我無法弄清楚你想要做什麼。 COM通常不是這麼難。當然選擇晚結合似乎是受虐狂。 –

+1

你說得對。 一切都變得困難。我們必須重拍 - 但沒有時間。 更準確地說,我們需要快速解決問題,然後纔有可能做得更好。 – SoapNewbie

+0

那麼,我仍然無法幫助你,因爲我仍然無法弄清楚你所做的和你所問的。也許別人可以。 –

回答

0

我做到了。 寫在這裏可能對我的決定有用。

起初,我有自己的TLB COM對象。寫在Delphi 7中。 還有一個在VS 2010中編寫的項目。他使用「Activator Class」創建了COM。然後通過後期的約束來完成這項工作。即通過InvokeMember。

的任務是這樣的:準備COM對象,它不能被替換。即有必要確保向後兼容性,並像以前一樣使用現有代碼。

但在同一時間,你必須編寫具有先進功能的另2個COM對象 - 支持多種新的方法。

我解決了這個問題,如下所示:德爾福7中創建一個單獨的TLB它宣佈了一個完全獨立的接口(從IDispatch接口繼承,但它並不重要)。 然後我創建了一個新的COM對象,它實現了舊界面和新界面。

然後修改了C#。他還通過「Activator Class」創建了對象,但創建後立即將創建的對象帶到操作符「as」的第二個接口(我在C#項目中導入了第二個TLB的描述)。如果結果是NULL,那麼它是一箇舊的COM不支持新功能。否則,我們有一個具有增強功能的新COM。

完成。