Results 1 to 9 of 9

Thread: COM object and QtVariant casting issue

  1. #1
    Join Date
    Jan 2017
    Location
    Spain
    Posts
    5
    Thanks
    4
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default COM object and QtVariant casting issue

    Hello every one,
    I'm trying to use a Windows COM object and I'm having trouble casting a returned function value. I am using Qt 5.7.0 and I got .h and .cpp file for COM object with dumpcpp tool. For simplicity I show only the kind of interest:

    Qt Code:
    1. class SCAPILIB_EXPORT IAttrList : public QAxObject
    2. {
    3. public:
    4. IAttrList(IDispatch *subobject = 0, QAxObject *parent = 0)
    5. : QAxObject((IUnknown*)subobject, parent)
    6. {
    7. internalRelease();
    8. }
    9.  
    10. /*
    11.   Method AddItem
    12.  
    13.   method AddItem
    14.  
    15.   */
    16. inline void AddItem(Attr Attribute, const QVariant& value);
    17.  
    18. /*
    19.   Method FindItemIndex
    20.  
    21.   method FindItemIndex
    22.  
    23.   */
    24. inline int FindItemIndex(int startIndex, SCAPILib::Attr Attribute);
    25.  
    26. /*
    27.   Method GetCount
    28.  
    29.   method GetCount
    30.  
    31.   */
    32. inline int GetCount();
    33.  
    34. /*
    35.   Method GetIndex
    36.  
    37.   method GetIndex
    38.  
    39.   */
    40. inline QVariant GetIndex(int index, Attr& pAttribute);
    41.  
    42. /*
    43.   Method GetItem
    44.  
    45.   method GetItem
    46.  
    47.   */
    48. inline QVariant GetItem(Attr Attribute);
    49.  
    50. /*
    51.   Method OutputToString
    52.  
    53.   method OutputToString
    54.  
    55.   */
    56. inline QString OutputToString();
    57.  
    58. /*
    59.   Method RestoreFromBlob
    60.  
    61.   method RestoreFromBlob
    62.  
    63.   */
    64. inline void RestoreFromBlob(QVariant blob);
    65.  
    66. /*
    67.   Method SaveToBlob
    68.  
    69.   method SaveToBlob
    70.  
    71.   */
    72. inline void SaveToBlob(QVariant& pBlob);
    73.  
    74. /*
    75.   Method SetIndex
    76.  
    77.   method SetIndex
    78.  
    79.   */
    80. inline void SetIndex(int index, SCAPILib::Attr Attribute, const QVariant& value);
    81.  
    82. // meta object functions
    83. static const QMetaObject staticMetaObject;
    84. virtual const QMetaObject *metaObject() const { return &staticMetaObject; }
    85. virtual void *qt_metacast(const char *);
    86. };
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. template<>
    2. struct QMetaTypeFunctionHelper<SCAPILib::IAttrList, /* Accepted */ true> {
    3. static void Destruct(void *t)
    4. {
    5. Q_UNUSED(t)
    6. static_cast<SCAPILib::IAttrList*>(t)->SCAPILib::IAttrList::~IAttrList();
    7. }
    8. static void *Construct(void *where, const void *t)
    9. {
    10. Q_ASSERT(!t);
    11. Q_UNUSED(t)
    12. return new (where) SCAPILib::IAttrList;
    13. }
    14. #ifndef QT_NO_DATASTREAM
    15. static void Save(QDataStream &stream, const void *t) { stream << *static_cast<const SCAPILib::IAttrList*>(t); }
    16. static void Load(QDataStream &stream, void *t) { stream >> *static_cast<SCAPILib::IAttrList*>(t); }
    17. #endif // QT_NO_DATASTREAM
    18. };
    To copy to clipboard, switch view to plain text mode 
    The function GetItem always returned a QVariant, usually the QVariant contain a QString, QInt or QBool, but with a determinate attribute the returned value will be a pointer to the base class(IAttrList *).

    Qt Code:
    1. inline QVariant IAttrList::GetItem(Attr Attribute)
    2. {
    3. QVariant qax_result;
    4. void *_a[] = {(void*)&qax_result, (void*)&Attribute};
    5. qt_metacall(QMetaObject::InvokeMetaMethod, 12, _a);
    6. return qax_result;
    7. }
    To copy to clipboard, switch view to plain text mode 

    I can use the function of the COM object just fine, except when it will be return a indicated class pointer. In this case de QVariant returnet type is (IUnknown *) and I not able to cast this to (IAttrLits *).

    I'm tried with:

    Qt Code:
    1. IAttrList * Attr = AttrList.GetItem(Some_Attribute).Value<IAttrList *>();
    To copy to clipboard, switch view to plain text mode 
    But compiler returned error: static assertion failed: qobject_cast requires the type to have a Q_OBJECT macro

    Which I understand is normal because, according to QT documentation, classes derived from QAxObject can not contain the Q_OBJECT macro.

    I have also tried with:

    Qt Code:
    1. IAttrList * attr = static_cast<IAttrList *>(AttrList.GetItem(Some_attribute).data());
    To copy to clipboard, switch view to plain text mode 
    and
    Qt Code:
    1. IAttrList * attr = static_cast<IAttrList *>(AttrList.GetItem(Some_attribute).value<void *>();
    To copy to clipboard, switch view to plain text mode 
    It's compile but the AttrList pointer does not seem to be valid because I get a segmentation fault to try use it.

    I have also read about the QueryInterface method and I have tried with something like:

    Qt Code:
    1. QVariant * var =AttrList.GetItem(some_attribute);
    2. HRESULT hr = AttrList.queryInterface(UuID,(void **)&var);
    To copy to clipboard, switch view to plain text mode 
    The problen is that this interface not have a UUID and I can't do the call.

    Also I have read about get a class instance with QuerySubOject but a QVariant Objects does not have it.

    I do not know how to solve it, any subgestion?. Thanks in advanced.
    Last edited by mlago; 3rd January 2017 at 09:50.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: COM object and QtVariant casting issue

    Try using "__uuidof( IAttrList )" where you wrote "UuID" in your queryInterface() call.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. The following user says thank you to d_stranz for this useful post:

    mlago (4th January 2017)

  4. #3
    Join Date
    Jan 2017
    Location
    Spain
    Posts
    5
    Thanks
    4
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: COM object and QtVariant casting issue

    Hi, thankyou for answer.

    I've tried how you say with error: error: '__mingw_uuidof' was not declared in this scope
    Qt Code:
    1. QVariant var = JswAttrList.GetItem(Some_attribute);
    2. HRESULT hr = AttrList.queryInterface(__uuidof(JSWSCAPILib::IJswAttrList),(void **)&var);
    To copy to clipboard, switch view to plain text mode 
    __uuidof is a MVC++ extensión. I have to say that I am using mingw as compiler. Them I've tried to get UUID Class from Visual C++ with this simple test:
    Qt Code:
    1. String^ s = __uuidof(JSWSCAPILib::IJswAttrList);
    To copy to clipboard, switch view to plain text mode 
    with this compiler error: error C2787: 'SCAPILib::IAttrList' : No GUIDs have been associated with this object

  5. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: COM object and QtVariant casting issue

    I think (void**)&var does not make sense, that is retinterpreting a pointer to a QVariant, no?

    You write that the QVariant type is IUnknown*, does this compile?
    Qt Code:
    1. IUnknown *obj = var.value<IUnknown*>();
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  6. The following user says thank you to anda_skoa for this useful post:

    mlago (4th January 2017)

  7. #5
    Join Date
    Jan 2017
    Location
    Spain
    Posts
    5
    Thanks
    4
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: COM object and QtVariant casting issue

    Thankyou for reply.
    Quote Originally Posted by anda_skoa View Post
    I think (void**)&var does not make sense, that is retinterpreting a pointer to a QVariant, no?
    In a sense yes.
    Quote Originally Posted by anda_skoa View Post
    You write that the QVariant type is IUnknown*, does this compile?
    Qt Code:
    1. IUnknown *obj = var.value<IUnknown*>();
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _
    Yes, compile Ok. What do you suggest?.
    Last edited by mlago; 4th January 2017 at 17:47.

  8. #6
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: COM object and QtVariant casting issue

    Quote Originally Posted by mlago View Post
    Yes, compile Ok. What do you suggest?.
    I haven't worked with COM or ActiveQt, but if the object is stored as a IUnknown in the QVariant, then just extract it as such and then use whatever API is provided for working with COM interfaces on that pointer.

    I.e. the QVariant is just a transport wrapper, like an envelope. You take the transported item out of the envelope and forget about the envelope.

    Cheers,
    _

  9. The following user says thank you to anda_skoa for this useful post:

    mlago (4th January 2017)

  10. #7
    Join Date
    Jan 2017
    Location
    Spain
    Posts
    5
    Thanks
    4
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: COM object and QtVariant casting issue

    It sounds really easy

    Seriously, I was thinking about something like that but still not know very well as how. What amazes me is that I can not do it any other way.

    I appreciate your effort.

  11. #8
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: COM object and QtVariant casting issue

    I've tried how you say with error: error: '__mingw_uuidof' was not declared in this scope
    So that sounds like mingw knows about it, but you haven't included the header file where it is defined. I don't use mingw, so I can't really tell you where to look. What does Google tell you if you paste "__mingw_uuidof" into the search box?
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  12. The following user says thank you to d_stranz for this useful post:

    mlago (5th January 2017)

  13. #9
    Join Date
    Jan 2017
    Location
    Spain
    Posts
    5
    Thanks
    4
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: COM object and QtVariant casting issue

    Hi,
    __uuidof is defined in _mingw.h
    Qt Code:
    1. #define __uuidof(type) __mingw_uuidof<__typeof(type)>()
    To copy to clipboard, switch view to plain text mode 
    The _mingw.h file begins by saying:
    Qt Code:
    1. /**
    2.  * This file has no copyright assigned and is placed in the Public Domain.
    3.  * This file is part of the mingw-w64 runtime package.
    4.  * No warranty is given; refer to the file DISCLAIMER.PD within this package.
    5.  */
    To copy to clipboard, switch view to plain text mode 
    and my compiler versión is 32 bits

    The most usable that I found in google is this thread https://forum.qt.io/topic/35324/solv...ce-to-canoe/15, but it is not applicable to me in the same way that it is exposed there. I've already tried compiling it with ole32.lib and nothing has changed.

    As I said I have also tried to capture the value returned by __uuidof in MS visual C ++ with the idea of using that UUID in my application in Qt. From this test what I consider relevant is the returned message by compiler error C2787: 'SCAPILib::IAttrList' : No GUIDs have been associated with this object. Which suggests to me that this class has no definite UUID. Then I have tried to define an IID_IATTRLIST variable in the IAttrList class without getting QueryInterface to return anything other than a null pointer. I think this is a dead end

Similar Threads

  1. casting object to enum in Qt
    By alizadeh91 in forum Qt Programming
    Replies: 1
    Last Post: 18th August 2012, 15:22
  2. Two dynamically created object interaction issue
    By kornicameister in forum Qt Quick
    Replies: 2
    Last Post: 9th September 2011, 11:35
  3. QtVariant pointer from QHash list
    By rmat in forum Qt Programming
    Replies: 3
    Last Post: 9th August 2011, 10:28
  4. Qt Webkit 2.1 - SVG Issue - Object overlapping
    By Tushar in forum Qt Programming
    Replies: 0
    Last Post: 29th December 2010, 08:32
  5. object handling issue
    By prolink007 in forum Qt Programming
    Replies: 1
    Last Post: 12th April 2010, 07:42

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.