声明

2010-01-11 47 views
0

的COM互操作的顺序我有一个接口的声明是这样的:声明

[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方法上设置了一个断点,然后查看dwOptions参数,它实际上包含一个IntPtr,它可以被转换为一个字符串 - 这恰好发生包含Start的第一个参数。

我认为这与声明的顺序有关,即使上面的声明是我所见过的规范声明。

另外,我觉得,如果我添加任意的IntPtr参数终止的定义,所以它看起来是这样的:

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

的方法还是成功地被调用带有字符串作为A1和其他指针字段正在填充130或看起来像另一个内存地址。

任何想法这里发生了什么? Start方法只需要5个参数。然而,在这里,我已经宣布终止6,并且它仍然被称为预计被称为Start的地方。

回答

1

确保通过比较生成的可调用包装和IDL文件来正确设置调度ID(dispid)。

1

你忘了3种IUnknown方法。 IInternetProtocolRoot :: Start()是vtable中的第四种方法。

+0

有趣。但是我在这里阅读http://msdn.microsoft.com/en-us/library/aa645736(VS.71).aspx,你没有在声明中包含IUnknown和IDispatch成员。 我很确定我在这里做了根本性的错误... – 2010-01-11 16:00:41

+0

该文章讨论了CLR内置的标准COM互操作支持。 [ComImport]你似乎在做自己的事情。 – 2010-01-11 16:24:25