2013-10-21 107 views
1

假設我有,我已經通過Activator.CreateInstance實例化一個COM對象:C#COM通過MethodInfo.Invoke進行互操作:int *參數?

object obj = Activator.CreateInstance(myGuid); 

現在,我知道這個對象有接受一個int *的函數作爲參數:

virtual void Method(int * outParameter) = 0; 

此方法只是將一個整數寫入outParameter。在C++中,我這樣做:

int parameter = 0; 
obj->Method(&parameter); 
// parameter now contains the result. 

我該怎麼辦通過MethodInfo.Invoke在C#中的相同呢?

MethodInfo method = obj.GetType().GetMethod("Method", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); 
method.Invoke(obj, ???); // What do I put here? 
+0

用OleView打開您的COM DLL,並向我們顯示您的Method的確切簽名,如IDL中所定義。我希望它看起來像'HRESULT方法([out] int * p)'我的答案適用。 – Noseratio

回答

1

你不能,這不是一個COM接口函數簽名。它必須必須返回一個HRESULT兼容,你必須自己用該方法的[PreserveSig]聲明接口,以便CLR知道不檢查返回值並拋出異常。它也缺少所需的__stdcall屬性(又名STDMETHOD),這是另一個COM要求。

你唯一的希望就是你得到了C++聲明錯誤。檢查最快的方法是使用動態關鍵字:

dynamic obj = Activator.CreateInstance(myGuid); 
int parameter; 
obj.Method(out parameter); 

或者,因爲它實際上看起來很像一個屬性的getter:

int parameter = obj.Method(); 

但與預期它會隨機拋出異常和/或不平衡的堆棧。需要徹底測試才能確保隨機返回值不會觸發異常。

然而,這是很多猜測,最好不要這樣做,特別是如果你確信簽名。改爲編寫一個C++/CLI包裝器。

+0

看來,我正在嘗試使用的對象不是一個適當的COM對象(可能爲什麼我不能直接實例化它)我現在正在C++/CLI包裝,雖然我是試圖避免這一點! – dsharlet

0

嘗試傳球int陣列與一個單一的元素parametersmethod.Invoke

var byrefArg = new int[1]; 
method.Invoke(obj, .... , new Object[] { byrefArg }, ...); 
var outParameter = byrefArg[0];