【发布时间】:2010-01-11 11:59:44
【问题描述】:
我有一个这样的接口声明:
[ComImport]
[Guid("79EAC9E4-BAF9-11CE-8C82-00AA004BA90B")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IInternetProtocol {
//IInternetProtcolRoot
void Start(
[ MarshalAs(UnmanagedType.LPWStr) ] string szURL,
IInternetProtocolSink Sink,
IInternetBindInfo pOIBindInfo,
UInt32 grfPI,
UInt32 dwReserved);
void Continue(ref _tagPROTOCOLDATA pProtocolData);
void Abort(Int32 hrReason, UInt32 dwOptions);
void Terminate(UInt32 dwOptions);
void Suspend();
void Resume();
//IInternetProtocol
[PreserveSig()] UInt32 Read(IntPtr pv, UInt32 cb, out UInt32 pcbRead);
void Seek(_LARGE_INTEGER dlibMove, UInt32 dwOrigin, out _ULARGE_INTEGER plibNewPosition);
void LockRequest(UInt32 dwOptions);
void UnlockRequest();
}
实现此接口的对象应该调用Start 方法。然而,这并没有发生。但奇怪的是,我发现调用的是 Terminate 方法,如果我在 Terminate 方法上设置断点,然后查看 dwOptions 参数,它实际上包含一个可以转换为字符串的 IntPtr - 这恰好包含 Start 的第一个参数。
我认为这与声明的顺序有关,尽管上面的声明是我在各处看到的规范声明。
另外,我发现如果我在 Terminate 的定义中添加任意 IntPtr 参数,它看起来像这样:
Terminate(IntPtr a1, IntPtr a2, IntPtr a3, IntPtr a4, IntPtr a5, IntPtr a6)
该方法仍被成功调用,该字符串作为 a1 中的指针,其他字段填充有 13 0 或其他内存地址。
知道这里发生了什么吗? Start 方法只需要 5 个参数。然而在这里,我已经用 6 声明了 Terminate,它仍然在预期调用 Start 的地方被调用。
【问题讨论】:
标签: c# com-interop