调用了错误的重载方法

时间:2011-02-02 12:31:28

标签: c# marshalling overloading

我在C#中编写了COM组件。接口方法以下列方式声明:

[ComImport,
    Guid("7D37EE00-143E-40DF-B177-BF091D7CD36A"),
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IMonogramServiceHost
{
    void Send(
        [In, MarshalAs(UnmanagedType.BStr)] string text);

    void Send([In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]byte[] data,
        [In, MarshalAs(UnmanagedType.I4)] int length);
}

这些方法是从C ++代码调用的。在C ++中声明的相同接口是:

DECLARE_INTERFACE_(IMonogramServiceHost, IUnknown)
{
    STDMETHOD(Send)(BSTR text);
    STDMETHOD(Send)(uint8 *buf, int length);
};

我正在呼叫第二种方法。它的参数只是unsigned char数组,其长度由参数'length'定义。通过一些未知的原因代码进入方法'void Send(string text)'。从COM方法返回后,调试器显示以下错误消息:

运行时检查失败#0 - ESP的值未在函数调用中正确保存。这通常是调用使用一个调用约定声明的函数的结果,函数指针使用不同的调用约定声明。

当我将方法重命名为ASend时,调用正确的版本。为什么会这样?我没有看到这个逻辑。

2 个答案:

答案 0 :(得分:2)

COM不支持函数重载。你打电话的方式并不清楚,但后期绑定肯定会失败。当被要求“发送”时,IDispatch :: GetIDsOfNames()将返回错误的dispid。在这种情况下,这并没有强烈表明,因为你派生自IUnknown。但本身就足以让这些方法具有不同的名称。

我建议使用SendText和SendBytes。非常合理,字节和字符在Unicode中完全不相同。

答案 1 :(得分:0)

C#char数组是C ++ uint16数组,而不是uint8数组。第二个签名是不匹配。