简体   繁体   English

p / invoke操作最终执行了另一个功能

[英]p/invoke operation ends up with executing another function

Not sure why this is happening, but when i execute one of my c# function, which could be defined by the following c# interface: 不知道为什么会这样,但是当我执行我的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);
}

and c++ interface: 和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 redirected to another function declared by a 'prior' interface. im重定向到由“先前”接口声明的另一个函数。 when i try to execute the following command for example: config->SetConfig(....). 当我尝试执行以下命令时,例如:config-> SetConfig(....)。 the function im redirected to(or next command to execute), is implemented by the base classs of IClosedCaptionsDecoder2 , which's called IClosedCaptionsDecoder . 重定向到(或要执行的下一个命令)的函数由IClosedCaptionsDecoder2的基类(称为IClosedCaptionsDecoder)实现

the c++ decleration of this interface is: 该接口的c ++定义为:

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

so config->SetConfig() actually invokes config->xxx(), my guess is that something is wrong with the offests of the functions. 因此config-> SetConfig()实际上会调用config-> xxx(),我猜这是该函数的缺点。

i even tried to define the entire relation in the c# side(the inheritance and so on) but that didn't work either. 我什至试图在c#端定义整个关系(继承等),但这也不起作用。

i would appreciate any help. 我将不胜感激任何帮助。 thanks! 谢谢!

Edit: when i tried to call GetConfig(), it actually executed SetConfig(). 编辑:当我尝试调用GetConfig()时,它实际上执行了SetConfig()。 so im definitly having problems with pointers offset or so. 所以我肯定有指针偏移量左右的问题。 each function, calls the previous one in the decleration order, how's it possible?? 每个函数都按脱位顺序调用前一个函数,这怎么可能?

Edit2 : i managed to solve this case by adding all functions to the IClosedCaptionsDecoder2 interface. Edit2 :我设法通过将所有函数添加到IClosedCaptionsDecoder2接口来解决这种情况。

This is a side-effect of a flaw in the way COM interop is implemented in the CLR. 这是在CLR中实现COM互操作的方式的缺陷的副作用。 It doesn't properly map methods of an interface to v-table slots when the interface derives from another interface other than IUnknown or IDispatch. 当接口从IUnknown或IDispatch以外的其他接口派生时,它无法将接口的方法正确映射到v表插槽。 It maps the first method to the first available slot even though it is already occupied by the methods of the inherited interface in the concrete coclass implementation. 即使第一个方法已被具体的coclass实现中的继承接口的方法占用,它仍将第一个方法映射到第一个可用插槽。 A side-effect of not supporting multiple inheritance. 不支持多重继承的副作用。 So what goes wrong is that when client code calls IClosedCaptionsDecoder::xxx(), it ends up calling IClosedCaptionsDecoder2::SetConfig() instead. 因此,出问题的是,当客户端代码调用IClosedCaptionsDecoder :: xxx()时,它将最终调用IClosedCaptionsDecoder2 :: SetConfig()。

The workaround is straight-forward though unpleasant, you have to flatten the interface so it includes the inherited methods. 解决方法虽然简单却令人不快,但您必须将接口展平,使其包含继承的方法。 In your case that will be: 在您的情况下,将是:

[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);
}

This becomes law in the USA on September 30th, only 6 weeks left to get this working ;) 该法律已于9月30日在美国成为法律,仅剩下6周的时间才能开始工作;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM