tags:

views:

24

answers:

2

I have an interface declaration like this:

[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();
}

The object that implements this interface is supposed to have it's Start method called. However, that is not happening. But curiously, I find that the Terminate method is being called instead, and if I set a break point on the Terminate method, and then look at the dwOptions parameter, it actually contains an IntPtr which can be cast into a string - which happens to contain what would be first parameter to Start.

I assume this has something to do with the order of declaration, even though the above declaration is the canonical one I've seen everywhere.

Also, I find that if I add arbitrary IntPtr arguments to the definition of Terminate so it looks like this:

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

the method is still successfully being called with the string as a pointer in a1 and other fields being populated with either 13 0 or what looks like another memory address.

Any idea what's going on here? The Start method only takes 5 parameters. Yet here, I've declared Terminate with 6 and its still being called in the place where Start is expected to be called.

+1  A: 

Make sure that the dispatch ids (dispid) are set correctly by comparing the generated callable wrapper with the IDL file.

arul
+1  A: 

You forgot the 3 IUnknown methods. IInternetProtocolRoot::Start() is the 4th method in the vtable.

Hans Passant
Interesting. But I read here http://msdn.microsoft.com/en-us/library/aa645736(VS.71).aspx that you don't include the IUnknown and IDispatch members in the declaration.I'm pretty sure I'm doing something fundamentally wrong here...
HS
That article discusses standard COM interop support built into the CLR. You seem to be doing your own though with [ComImport].
Hans Passant