2012-08-16 35 views
1

不知道爲什麼會這樣,但是當我執行我的C#功能,可以通過下面的C#接口定義的一個:的P/Invoke操作結束了執行其他功能

[ComImport, Guid("EA5435EA-AA5C-455d-BF97-5F19DC9C29AD"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
public interface IClosedCaptionsDecoder2 
{ 
    [PreserveSig] 
    int SetConfig([In] ref ClosedCaptionsDecoderConfig config); 
    [PreserveSig] 
    int GetConfig([Out] out ClosedCaptionsDecoderConfig config); 
} 

和C++接口:

interface __declspec(uuid("{EA5435EA-AA5C-455d-BF97-5F19DC9C29AD}")) 
    IClosedCaptionsDecoder2 : public IClosedCaptionsDecoder 
    { 
     STDMETHOD(SetConfig)(IN CLOSEDCAPTIONSDECODERCONFIG& config) PURE; 
     STDMETHOD(GetConfig)(OUT CLOSEDCAPTIONSDECODERCONFIG* pConfig) PURE; 
    }; 

im被重定向到另一個由'prior'接口聲明的函數。 當我嘗試執行以下命令,例如: config-> SetConfig(....)。函數im被重定向到(或下一個執行的命令),由基類IClosedCaptionsDecoder2實現,其稱爲IClosedCaptionsDecoder

C++的這個接口的decleration是:

interface __declspec(uuid("{26B8D7F1-7DD8-4a59-9663-8D00C03135F7}")) 
     IClosedCaptionsDecoder : public IUnknown 
     { 
      STDMETHOD(xxx)(IExternalCCObserver* pObserver, LONG lFlags) PURE; 
     }; 

所以config->調用setConfig()實際上調用config-> XXX(),我的猜測是,什麼是錯用的功能offests。

我甚至試圖定義在c#端(繼承等)的整個關係,但也沒有工作。

我將不勝感激任何幫助。 謝謝!

編輯:當我試圖調用GetConfig()時,它實際上執行了SetConfig()。所以即時通訊指針偏移等問題。每個函數都會調用前一個函數,這怎麼可能?

Edit2:我設法通過將所有函數添加到IClosedCaptionsDecoder2接口來解決這個問題。

+0

應該不是C#接口也從一個基地一個衍生,作爲C++接口是什麼? – Dialecticus 2012-08-16 09:04:54

+0

嘗試過,沒有工作 – 2012-08-16 09:05:49

+0

通過在第二個接口中聲明所有功能來解決案例 – 2012-08-16 09:06:49

回答

1

這是在CLR中實現COM互操作的方式中的一個缺陷的副作用。當接口從IUnknown或IDispatch以外的其他接口派生時,它無法正確映射接口的方法到v-table插槽。它將第一個方法映射到第一個可用插槽,即使它已被具體coclass實現中的繼承接口的方法佔用。不支持多重繼承的副作用。所以出現問題的是,當客戶端代碼調用IClosedCaptionsDecoder :: xxx()時,它最終會調用IClosedCaptionsDecoder2 :: SetConfig()。

解決方法雖然很直接,但不愉快,您必須將界面變平,以便它包含繼承的方法。在你的情況,這將是:

[ComImport, Guid("EA5435EA-AA5C-455d-BF97-5F19DC9C29AD"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
public interface IClosedCaptionsDecoder2 
{ 
    // Methods inherited from IClosedCaptionsDecoder: 
    [PreserveSig] 
    int xxx(whatever...); 
    // Methods specific to IClosedCaptionsDecoder2 
    [PreserveSig] 
    int SetConfig([In] ref ClosedCaptionsDecoderConfig config); 
    [PreserveSig] 
    int GetConfig([Out] out ClosedCaptionsDecoderConfig config); 
} 

這成爲法律,在美國9月30日,它僅有6周留下來得到這個工作;)