C# p/invoke操作以执行另一个函数结束

C# p/invoke操作以执行另一个函数结束,c#,c++,marshalling,com-interop,com-interface,C#,C++,Marshalling,Com Interop,Com Interface,不确定为什么会发生这种情况,但当我执行一个c#函数时,它可以由以下c#接口定义: [ComImport, Guid("EA5435EA-AA5C-455d-BF97-5F19DC9C29AD"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IClosedCaptionsDecoder2 { [PreserveSig] int SetConfig([In] ref ClosedCap

不确定为什么会发生这种情况,但当我执行一个c#函数时,它可以由以下c#接口定义:

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

和C++接口:

[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);
}
    interface __declspec(uuid("{EA5435EA-AA5C-455d-BF97-5F19DC9C29AD}"))
    IClosedCaptionsDecoder2 : public IClosedCaptionsDecoder
    {
        STDMETHOD(SetConfig)(IN CLOSEDCAPTIONSDECODERCONFIG& config) PURE;
        STDMETHOD(GetConfig)(OUT CLOSEDCAPTIONSDECODERCONFIG* pConfig) PURE;
    };
im重定向到“Previor”接口声明的另一个函数。 例如,当我尝试执行以下命令时: 配置->设置配置(..)。im重定向到的函数(或要执行的下一个命令)由IClosedCaptionDecoder2的基类实现,该基类称为IClosedCaptionDecoder

此接口的C++解密为:

interface __declspec(uuid("{26B8D7F1-7DD8-4a59-9663-8D00C03135F7}"))
        IClosedCaptionsDecoder : public IUnknown
        {
            STDMETHOD(xxx)(IExternalCCObserver* pObserver, LONG lFlags) PURE;
        };
所以config->SetConfig()实际上调用了config->xxx(),我的猜测是函数的提供有问题

我甚至试图在c#端定义整个关系(继承等),但这也不起作用

我将感谢任何帮助。 谢谢

Edit:当我试图调用GetConfig()时,它实际上执行了SetConfig()。所以我肯定会遇到指针偏移量之类的问题。每一个函数,调用前一个在去宽容顺序,怎么可能


Edit2:我通过向IClosedCaptionDecoder2接口添加所有函数来解决此问题。

这是CLR中COM互操作实现方式中存在缺陷的副作用。当接口派生自IUnknown或IDispatch以外的其他接口时,它不会正确地将接口的方法映射到v-table插槽。它将第一个方法映射到第一个可用插槽,即使它已经被具体的coclass实现中继承接口的方法占用。不支持多重继承的副作用。所以问题在于,当客户端代码调用IClosedCaptionDecoder::xxx()时,它最终会调用IClosedCaptionDecoder2::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周的时间了;)

这是在CLR中实现COM互操作的方式存在缺陷的副作用。当接口派生自IUnknown或IDispatch以外的其他接口时,它不会正确地将接口的方法映射到v-table插槽。它将第一个方法映射到第一个可用插槽,即使它已经被具体的coclass实现中继承接口的方法占用。不支持多重继承的副作用。所以问题在于,当客户端代码调用IClosedCaptionDecoder::xxx()时,它最终会调用IClosedCaptionDecoder2::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周的时间了;)

是否应该从一个基础接口派生C接口,因为C++接口是通过声明第二个接口中的所有函数来解决这个问题的,请不要改变问题的标题,以将问题标记为关闭。相反,请在答案旁边单击正确的答案并标记答案。是否应该将C接口也从基础的派生出来,因为C++接口是通过声明第二个接口中的所有函数来解决这个问题的,请不要改变问题的标题,以将问题标记为关闭。相反,发布你的正确答案,点击答案旁边的空心复选标记,将答案标记为正确。