2012-09-24 97 views
1

我有一個用C#編寫的基類,它實現了在IDL庫中定義的接口。我有一個C++類來管理這個類的單個實例。我也有一個C#項目需要使用這個類[實例(通過C++項目獲得)]。我想將我的基類實現的COM接口轉換回我的C#基類。將COM對象轉換爲C#/ .NET類時遇到問題

但是,當我將從C++比例獲得的通用對象轉換到我的C#基類中時,我收到一個錯誤。當我將它投射到衍生界面時,沒有問題。

下面是我的問題的類似示例。在CSDriver的NETBaseInstance函數中從不評估兩個if範圍。 NETBase是唯一實現COMInterface的類。所以,我知道這個值是一個NETBase,因爲如果對COMInterface的範圍進行評估。

public class NETBase : COMInterface{ ... } 

public class CSDriver{ 
    private NETBase m_NETBaseInstance; 

    ... 

    public object NETBaseInstance{ 
     set{ 
      COMInterface test; 
       if(value is COMInterface){ 
       // This is evaluated. 
       test = value as COMInterface; 
      } 

      if(value is NETBase){ 
       // This is not evaluated. 
       m_NETBaseInstance = value as NETBase; 
      } 

      if(test is NETBase){ 
       // This is not evaluated. 
       m_NETBaseInstance = test as NETBase; 
      } 
     } 
    } 
} 

將此COM對象成功投射到C#對象的過程是什麼?難道我做錯了什麼?

非常感謝您提供任何答案。

回答

1

您無法直接投射。

非託管C++ API正在返回指向COMInterface接口vtable的指針;你可能會認爲你知道NETBase是這個接口的唯一實現,但是.NET COM Interop基礎結構沒有這樣的知識(事實上,嚴格地說你錯了,因爲非託管代碼正在處理的COMInterface的實現是一個COM Callable Wrapper由interop基礎結構創建,而不是NETBase的實例);當你從C#調用C++ API時,所有的.NET interop層可以做的就是將託管代碼傳遞給非託管COM接口周圍的Runtime Callable Wrapper,並且此RCW不是NETBase的實例,因此無法將其轉換爲NETBase,正如你所發現的那樣。

可能有解決方法來做你想做的事情,利用你的特殊知識,任何COMInterface必須指向特定的NETBase實例。細節將取決於NETBase的性質(例如,它的狀態是可序列化的)以及所有託管代碼是否在同一個AppDomain中運行(例如,如果是的話,您可能能夠在.NETBase類上提供靜態字段和方法允許與COMInterface指向的實例會合 - 如果它真的是一個單例,就像你的問題所建議的那樣)。

+0

是的,你是對的;這是一個單身人士。我曾想過在NETBase中管理單例,並按照你的建議來做同樣的事情,但我的團隊並不想要一個與其他人不同的類。所以,我打算自己打包NETBase(而其他類有一個包裝和類本身)。謝謝你的答案。這真的很有幫助。 – swtdrgn

相關問題