2012-08-16 36 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周留下来得到这个工作;)