Com Interop声明顺序

时间:2010-01-11 11:59:44

标签: c# com-interop

我有这样的接口声明:

[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的第一个参数。

我认为这与声明的顺序有关,即使上述声明是我在任何地方都看到的规范声明。

另外,我发现如果我将任意IntPtr参数添加到Terminate的定义中,那么它看起来像这样:

Terminate(IntPtr a1, IntPtr a2, IntPtr a3, IntPtr a4, IntPtr a5, IntPtr a6)

该方法仍然成功调用,字符串作为a1中的指针,其他字段填充了13 0或看起来像另一个内存地址。

知道这里发生了什么吗? Start方法只需要5个参数。然而,在这里,我已经宣布终止为6,并且仍然会在预计将调用Start的地方调用它。

2 个答案:

答案 0 :(得分:1)

通过将生成的可调用包装器与IDL文件进行比较,确保正确设置了调度ID(dispid)。

答案 1 :(得分:1)

你忘记了3个IUnknown方法。 IInternetProtocolRoot :: Start()是vtable中的第4个方法。