Reading COM struct from IDispatch
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7

Thread: Reading COM struct from IDispatch

  1. #1
    Join Date
    Jan 2006
    Posts
    28

    Reading COM struct from IDispatch

    Hi,

    First of all, I do not know where to post the question in subcategory.

    My question is that I have C++ function which has a IDispatch input as argument.

    I am trying to read the struct from IDispatch.

    So basically, the struct definition is

    struct MyStruct
    {
    void *m_pValue;
    };


    I can get the ITypeInfo and read the whole structure definition from it.

    But I do not know how to read the struct instance value.

    I am dumping all the info from ITypeInfo


    TYPEATTR
    ========
    guid {A1CB710C-8D50-3181-BB38-65CE2E98F9A6} _GUID
    lcid 0x00000000 unsigned long
    dwReserved 0x00000000 unsigned long
    memidConstructor 0xffffffff long
    memidDestructor 0xffffffff long
    lpstrSchema 0x00000000 <NULL> wchar_t *
    cbSizeInstance 0x00000004 unsigned long
    typekind TKIND_RECORD (0x00000001) tagTYPEKIND
    cFuncs 0x0000 unsigned short
    cVars 0x0001 unsigned short
    cImplTypes 0x0000 unsigned short
    cbSizeVft 0x0000 unsigned short
    cbAlignment 0x0004 unsigned short
    wTypeFlags 0x0000 unsigned short
    wMajorVerNum 0x0001 unsigned short
    wMinorVerNum 0x0000 unsigned short
    tdescAlias {lptdesc=0xbaadf00d {lptdesc=??? lpadesc=??? hreftype=??? ...} lpadesc=0xbaadf00d {tdescElem={lptdesc=...} ...} ...} tagTYPEDESC
    idldescType {dwReserved=0x00000000 wIDLFlags=0x0000 } tagIDLDESC

    VARDESC[0]
    ==========
    memid 0x40000000 long
    lpstrSchema 0x00000000 <NULL> wchar_t *
    oInst 0x00000000 unsigned long
    lpvarValue 0x00000000 <NULL> tagVARIANT *
    elemdescVar tagELEMDESC
    tdesc tagTYPEDESC
    lptdesc 0x003e32f8 tagTYPEDESC *
    lptdesc 0x00000000 <NULL> tagTYPEDESC *
    lpadesc 0x00000000 <NULL> tagARRAYDESC *
    hreftype 0x00000000 unsigned long
    vt 0x0018 unsigned short
    lpadesc 0x003e32f8 tagARRAYDESC *
    hreftype 0x003e32f8 unsigned long
    vt 0x001a unsigned short
    idldesc {dwReserved=0x00000000 wIDLFlags=0x0000 } tagIDLDESC
    paramdesc {pparamdescex=0x00000000 <NULL> wParamFlags=0x0000 } tagPARAMDESC
    wVarFlags 0x0000 unsigned short
    varkind VAR_PERINSTANCE (0x00000000) tagVARKIND



    Any help will be highly appreciated.

    Regards.

  2. #2
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,957

    Re: Reading COM struct from IDispatch

    First thing you have to learn about COM is: COM is not C++. COM world knows nothing about C++ structures. COM knows nothing about any language specific constructs. COM knows only about COM.

    The only generic way to pass some structured data via COM interfaces is passing COM objects.

    There is a way to pass language specific types, though with limited support, and the way is called special marshaling. But as far as I know, IDispatch is intended to operate with universal marshaling compliant types, and the easiest way is again passing COM object's dispinterface.

    Bottom line: you have to turn your C++ structure to a real COM object prior to letting it to COM world.
    Best regards,
    Igor

  3. #3
    Join Date
    Jan 2006
    Posts
    28

    Re: Reading COM struct from IDispatch

    I totally agree with you. But i am confused over unmanaged C++ function call from C#.

    Basically, I am trying to get IOleObject interface from the user control in unmanaged function. But everytime QueryInterface returns E_NOINTERFACE.

    Then I walked through the ITypeInfo from IDispatch interface and found out that it is basically a intPtr structure in IDispatch routine.

    Here is what I am trying to do.

    C++

    void MyFunc(IDispatch *pDisp)

    {

    IOleObject *pOleObject;

    HRESULT hr = pDisp->QueryInterface(IID_IOleObject, (LPVOID *)&pOleObject );

    // Always return hr = E_NOINTERFACE

    }

    C#

    static extern void MyFunc([In, MarshalAs(UnmanagedType.IDispatch)] Object o);

    void ManagedFunc()

    {

    UserControl uc1 = new UserControl();

    IntPtr unk = Marshal.GetIUnknownForObject(uc1);

    MyFunc(unk);

    }

    Kindly tell me how to access IOleObject from the winform control. I can't use managed code in my Unmanaged library.

    Thanks for the help.
    Regards.

  4. #4
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    3,826

    Re: Reading COM struct from IDispatch

    Quote Originally Posted by Igor Vartanov View Post
    The only generic way to pass some structured data via COM interfaces is passing COM objects.
    No, that's an incorrect view of things...

    COM is about interfaces (functions) and you don't know what the "inside" (data) of a COM interface really is. Although it does happen, it's rare to see COM interfaces where you pass one COM 'object' into another COM 'object'. technically speaking 'COM object' isn't a right terminology, it's an instance of a COM interface.

    passing data to/from COM interfaces is about using "agreed upon" data formats.
    Generically this means you have:
    - the elementary types like an BYTE, SHORT, INT, LONG, DATE...
    - The string type BSTR
    - The VARIANT
    - The SAFEARRAY
    Non-generically, you can technically use "any type" you want, including (pointers to) C++ structures and even C++ classes, but that means that particular member function will probably not be accessible/callable from anything but C++ or at least from any language that doesn't provide for specific memory organized data layouts.
    In extreme cases, the presense of such memberfunctions might make the whole interface invalid on some platforms/languages. Part of the point of COM is about making some interface that is accessible for "any language", so using such constructs while possible, kind of makes you wonder why you went to COM in the first place if it's only accessible from C++


    IDispatch is about offerring interfaces which are "interpreted" at runtime rather than "hardcoded" function calls determined at compiletime, it's what languages like VBS/VBA and JavaScript tend to use. ANd those languages will only work with the generic types.
    You can call IDispatch from C++ but without some framework support for it (like ATL), it's very tedious compared to the fairly straightforward calling of interface methods.
    Last edited by OReubens; April 2nd, 2014 at 06:44 AM.

  5. #5
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,957

    Re: Reading COM struct from IDispatch

    Quote Originally Posted by salman83 View Post
    Kindly tell me how to access IOleObject from the winform control. I can't use managed code in my Unmanaged library.
    I'm not sure how I could help, as I know nothing about what you do and how you do what you do. I tried to assemble some sample that demonstrates how true COM object and native Object in C# differ from each other. Please find the sample attached here.

    When you have the project built, run it with demo or xl command parameter to see how true COM object is passed via IUnknown to C++ code. You are going to get Succeeded in case you have demo scriptlet or MS Excel registered in your system (see README.TXT for scriptlet registration details.) Which means C++ is able to query IDispatch from the IUnknown.

    And see the same for native C# Object when you specify no command line parameter. You get Failed, which means there's no any dispinterface behind the IUnknown.

    See the difference.
    Attached Files Attached Files
    Last edited by Igor Vartanov; April 2nd, 2014 at 10:33 AM.
    Best regards,
    Igor

  6. #6
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,957

    Re: Reading COM struct from IDispatch

    Quote Originally Posted by OReubens View Post
    No, that's an incorrect view of things...

    COM is about interfaces (functions) and you don't know what the "inside" (data) of a COM interface really is.
    Yeah, I should be more specific about interfaces. But once some interface is registered in the system (along with its coclass) you do know "what is inside" as the type library exposes the details. The thing is that type library can talk COM language only.
    Best regards,
    Igor

  7. #7
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    5,957

    Re: Reading COM struct from IDispatch

    I've built another sample, now with winforms app. Everything seems working fine, and IOleObject is retrievable alright, at least from button object.
    Attached Files Attached Files
    Best regards,
    Igor

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center