C# Com互操作声明顺序
我有这样一个接口声明:C# Com互操作声明顺序,c#,com-interop,C#,Com Interop,我有这样一个接口声明: [ComImport] [Guid("79EAC9E4-BAF9-11CE-8C82-00AA004BA90B")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IInternetProtocol { //IInternetProtcolRoot void Start( [ MarshalAs(UnmanagedType.LPWStr) ] s
[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();
}
Terminate(IntPtr a1, IntPtr a2, IntPtr a3, IntPtr a4, IntPtr a5, IntPtr a6)
实现此接口的对象应该调用其Start
方法。然而,这并没有发生。但奇怪的是,我发现正在调用Terminate方法,如果我在Terminate方法上设置一个断点,然后查看dwOptions参数,它实际上包含一个可以转换为字符串的IntPtr,该字符串恰好包含第一个开始的参数
我假设这与声明的顺序有关,尽管上面的声明是我在任何地方都见过的规范声明
此外,我发现,如果我在Terminate的定义中添加任意IntPtr参数,那么它看起来是这样的:
[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();
}
Terminate(IntPtr a1, IntPtr a2, IntPtr a3, IntPtr a4, IntPtr a5, IntPtr a6)
方法仍在成功调用中,字符串作为a1中的指针,其他字段填充有13
0
或类似于另一个内存地址的内容
知道这是怎么回事吗?Start方法只需要5个参数。但是在这里,我已经声明了Terminate with 6,并且它仍然在预期调用Start的位置被调用。通过比较生成的可调用包装与IDL文件,确保调度ID(
dispid
)设置正确。您忘记了3个IUnknown方法。IInternetProtocolRoot::Start()是vtable中的第四个方法。很有趣。但我在这里读到你没有把IUnknown和IDispatch成员包括在声明中。我很确定我在这里犯了一些根本性的错误……那篇文章讨论了CLR中内置的标准COM互操作支持。你似乎在用[ComImport]做你自己的事情。