聲明

2010-01-11 60 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