Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Com互操作声明顺序_C#_Com Interop - Fatal编程技术网

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]做你自己的事情。