none
.Net/COM Event Interop cast issue RRS feed

  • Question

  • .Net Framework 4.0
    VS 2012

    We have a C# Project implementing some COM-Objects, this depends on an existing tlb.

    The "normal" importing of tlb inside Visual Studio dosen't work, so we using: tlbimp with /strict /sysarray ref:nopia

    This .Net project has also an EventSource for the COM.

    Now our problem:

    If the COM Interface query for some .Net-COM Interfaces all works fine.
    The EventCalls works fine.
    But if the Event Interface send a .Net-COM Interface as an Parameter only an IDispatch will be send not the real IDrawing-Interface. See comments in ClSampleEvents::raw_eventOpenComplete

    sample code:

    // C# COM Implementation Class
    [ComVisible(true)]
    public class DrawingImp : TLBNamespace.Drawing
    {
      ...
    }
    
    // C# IEvents interface
    [ComVisible(true)]
    [GuidAttribute("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IPdmEvents
    {
    ...
      [ComVisible(true)]
      [System.Runtime.InteropServices.DispId(XX)]
      void eventOpenComplete(TLBNamespace.Drawing Drawing);
    }
    
    // C# Event Class
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.AutoDual)] 
    [ComSourceInterfaces(typeof(IEvents))]
    [GuidAttribute("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")]
    public class EventsImp : TLBNamespace.Events, IProvideClassInfo2
    {
    ...
      public void FireOpenComplete(TLBNamespace.Drawing Drawing)
      { eventOpenComplete(Drawing); }
    }
    
    // send event
    {
      DrawingImp pDI = new DrawingImp();
      EventsImp.FireOpenComplete(pDI);
    }

    The the soure idl  which generate the used tlb:

    [ object, oleautomation, uuid(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX), dual, helpstring("sample interface") pointer_default(unique), nonextensible ] interface IDrawing : IDispatch { ... } [ uuid(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX), helpstring("sample CoClass"), noncreatable ] coclass Drawing { [default] interface IDrawing; }; [ uuid(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX), helpstring("sample events interface"), ] dispinterface _ICdnCADApiEvents { [id(XX), helpstring("Sample event method")] HRESULT eventOpenComplete([in] IDrawing *drawing); }

    And the C++ code:

    class ClSampleEvents : public IDispEventImpl<1, ClSampleEvents,&__uuidof(_IClSampleEventsEvents),&GUID_NULL,0xFFFF,0xFFFF>
    {
    ...
      STDMETHOD(raw_eventOpenComplete)(IDrawing * Drawing);
    }
    
    ///////////////////////////////////////////////////////////HRESULT ClSampleEvents ::raw_eventOpenComplete(IDrawing * Drawing)
    {
      // if I using these casts all works fine
      IDispatchPtr pDisp = Drawing; // pDisp has same baseaddress as Drawing so I think Drawing was send from .Net as IDispatch not as IDrawing
      IDrawingPtr pDrw = pDisp;
      VARIANT_BOOL vb;
      pDrw->get_SampleFunc(&vb); // <-- this works fine
    
      VARIANT_BOOL vb;
      Drawing->get_SampleFunc(&vb); // <-- this may crash or call wrong function depending 
    
      return S_OK;
    }
    
    Any hints are welcome
    Friday, January 11, 2013 10:54 AM

All replies

  • Hi RGerlach,

    Thank you for your question.

    I am trying to involve someone familiar with this topic to further look at this issue. There might be some time delay. Appreciate your patience.
     
    Thank you for your understanding and support.


    Min Zhu
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, January 16, 2013 1:28 AM
    Moderator