ActiveQt: Export array of QObjects to OLE



  • I'm still learning my through through OLE (mostly trial and error) and I was wondering if there is a way to export an array of QObject*?
    I have successfully exposed a single QObject* (transforms into IDispatch) and arrays of QVariant but is SAFEARRAY(IDispatch*) supported?

    Thanks in advance for your help, yes you @hskoglund I know you are our OLE guru!



  • Hi, aaaahh you mentioned SAFEARRAY, brings back fond memories from around the turn of the century, struggling with MFC and OLE :-) (One particular nasty thing I remember about SAFEARRAYs, when you allocate an array to receive some stuff, if you don't clear every byte to 0 in the array at start, OLE will die on you horribly.)

    Ok, interesting question, give me a few hours I'll try a simple program and get back to you...



  • I knew you would come to the rescue.
    A while ago I sent you a chat message to which you never answered, I'll copy it here:

    Hello Henry, you've helped me a lot with activeQt and COM servers on this forum. Unfortunately I'm still stuck with basic questions (like the one I've posted here) and I was wondering if you know any consultant (you!) that would provide mentoring on this topic? Thanks in advance



  • I believe it's just not possible



  • Hi, sorry about ".. give me a few hours .." a bit too optimistic :-)
    Anyway when you said " ... not possible" I just had to look into it:

    As yet I haven't got a finished example. but I've solved the main riddle, how to export/expose a SAFEARRAY of IDispatch* chaps: in the old days when using Visual Studio you could pretty much could export anything from your C++ to OLE, but it was a lot of fiddling with the .idl input file to the MIDL compiler (that's the Microsoft tool that creates a.tlb file from an .idl file).

    When using Qt you get all of this for free (through the idc.exe tool, that creates the .idl file from your .exe file) but for a price: you lose the flexibility of exporting all kinds of weird stuff to OLE, instead you are restricted to a subset of properties and data types, for example you can only export a SAFEARRAY of VARIANTs (through a QVariantList). The list of valid OLE types is in Qt's source if you want to see it. But I take this restriction anyday because it makes dealing with OLE so much easier. Unless of course you want to bypass those restrictions, like in your example above.

    So to export a SAFEARRAY of IDispatch* pointers, we have to find a way past the strict eyes of Qt's idc.exe compiler. I use 2 #defines and C's text preprocessor to "edit" the .idl file after it is written by the idc.exe program. (Remember there's no .idl file to patch, it is rewritten completely after the linking step.)

    I made an example SafeArrayTest, a simple widget .dll, here's the relevant part:

    ...
    `#include <comdef.h>     // get OLE_COLOR from here
    
    class SafeArrayTest : public QWidget
    {
        Q_OBJECT
        Q_CLASSINFO("ClassID",    "{DF168452-A2CD-4AAB-A982-6B9840E74661}")
        Q_CLASSINFO("InterfaceID","{616F6205-31C5-4410-A74E-8B81C76FAFE2}")
        Q_CLASSINFO("EventsID",   "{E1816BB3-1F5D-4A31-9855-E6BA432055F3}")
        Q_PROPERTY( OLE_COLOR dispatchArray READ dispatchArray )
    ...
    

    So we have a dispatchArray property of the type OLE_COLOR (which is kosher for the idc.exe compiler) but then after idc.exe has created the .idl we pass along 2 #defines to the command line of Microsoft's MIDL compiler, by adding this to the .pro file:

    ...
    # expect our OLE property to be named "dispatchArray" with the dummy type OLE_COLOR
    QMAKE_IDL = midl /D OLE_COLOR=SAFEARRAY /D dispatchArray=(IDispatch*)dispatchArray
    

    Now, if I create a simple Visual Basic program and add a reference to the SafeArrayTest.dll, Visual Basic says that the property dispatchArray is an Array of Objects.

    I haven't finished that test program yet, but at least the OLE exposing is solved I think...
    I'll post again sooooon..


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.