我在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时,调用正确的版本。为什么会这样?我没有看到这个逻辑。
答案 0 :(得分:2)
COM不支持函数重载。你打电话的方式并不清楚,但后期绑定肯定会失败。当被要求“发送”时,IDispatch :: GetIDsOfNames()将返回错误的dispid。在这种情况下,这并没有强烈表明,因为你派生自IUnknown。但本身就足以让这些方法具有不同的名称。
我建议使用SendText和SendBytes。非常合理,字节和字符在Unicode中完全不相同。
答案 1 :(得分:0)
C#char数组是C ++ uint16数组,而不是uint8数组。第二个签名是不匹配。