2017-01-02 9 views
1

Я пытаюсь использовать COM-объект, и у меня возникли проблемы с возвратом возвращаемого значения функции. Я использую Qt 5.7.0, и я получил файлы .h и .cpp для COM-объекта с помощью инструмента dumpcpp.COM-объект и возвращаемый вопрос QVariant casting

class SCAPILIB_EXPORT IAttrList : public QAxObject 
{ 
public: 
    IAttrList(IDispatch *subobject = 0, QAxObject *parent = 0) 
    : QAxObject((IUnknown*)subobject, parent) 
    { 
     internalRelease(); 
    } 

    /* 
    Method AddItem 

    method AddItem 

    */ 
    inline void AddItem(Attr Attribute, const QVariant& value); 

    /* 
    Method FindItemIndex 

    method FindItemIndex 

    */ 
    inline int FindItemIndex(int startIndex, SCAPILib::Attr Attribute); 

    /* 
    Method GetCount 

    method GetCount 

    */ 
    inline int GetCount(); 

    /* 
    Method GetIndex 

    method GetIndex 

    */ 
    inline QVariant GetIndex(int index, Attr& pAttribute); 

    /* 
    Method GetItem 

    method GetItem 

    */ 
    inline QVariant GetItem(Attr Attribute); 

    /* 
    Method OutputToString 

    method OutputToString 

    */ 
    inline QString OutputToString(); 

    /* 
    Method RestoreFromBlob 

    method RestoreFromBlob 

    */ 
    inline void RestoreFromBlob(QVariant blob); 

    /* 
    Method SaveToBlob 

    method SaveToBlob 

    */ 
    inline void SaveToBlob(QVariant& pBlob); 

    /* 
    Method SetIndex 

    method SetIndex 

    */ 
    inline void SetIndex(int index, SCAPILib::Attr Attribute, const QVariant& value); 

// meta object functions 
    static const QMetaObject staticMetaObject; 
    virtual const QMetaObject *metaObject() const { return &staticMetaObject; } 
    virtual void *qt_metacast(const char *); 
}; 

Функция GetItem всегда возвращается в QVariant, как правило, содержат QVariant QString, Qint или QBool, но с детерминированной атрибут возвращаемое значение будет указателем на базовый класс (IAttrList *).

inline QVariant IAttrList::GetItem(Attr Attribute) 
{ 
    QVariant qax_result; 
    void *_a[] = {(void*)&qax_result, (void*)&Attribute}; 
    qt_metacall(QMetaObject::InvokeMetaMethod, 12, _a); 
    return qax_result; 
} 

Я могу использовать функцию COM-объекта просто отлично, за исключением случаев, когда будет возвращен указанный указатель класса. В этом случае тип возвращаемого типа QVariant - это (IUnknown *), и я не могу передать это (IAttrLits *).

Я попытался с:

IAttrList * Attr = AttrList.GetItem(Some_Attribute).Value<IAttrList *>(); 

Но компилятор возвращается ошибка: статическое утверждение не выполнено: qobject_cast требует типа иметь Q_OBJECT макроса

Что я понимаю, это нормально, потому что, согласно документации QT , классы, полученные из QAxObject, не могут содержать макрос Q_OBJECT.

Я также попытался с:

IAttrList * attr = static_cast<IAttrList *>(AttrList.GetItem(Some_attribute).data()); 

и

IAttrList * attr = static_cast<IAttrList *>(AttrList.GetItem(Some_attribute).value<void *>(); 

Это компилировать, но указатель AttrList не кажется действительным, потому что я получаю ошибку сегментации, чтобы попытаться использовать его.

Я не знаю, в чем проблема, может быть любая задержка ?. Заранее спасибо.

+1

вы должны использовать QueryInterface в IUnkown с запросом интерфейса, который вы желаете. Вы не должны делать допущения в COM, что IUnkown напрямую зависит от типа, который вы хотите. – Jonathan

+0

Спасибо за ответ, Я не уверен в использовании queryinterface. Вы ссылаетесь на что-то вроде этого? QVariant var = AttrList.GetItem (some_attribute); AttrList.queryInterface (some_UUID, (void **) var); Как получить UUID для класса IAttrList ?. Еще раз спасибо. – mlago

+0

К сожалению, у меня нет или нет Qt ... поэтому я не могу ответить на специфику библиотеки. UUID - это число, если вы сделали импорт typelib, для этого часто будет константа. queryInterface должен быть выполнен на объекте IUnkown, который вы получили как возвращаемое значение. Это требует, чтобы указатель был разрешен к классу этого интерфейса.В противном случае он вернет ошибку, если интерфейс не поддерживается. Почему вы должны это делать, потому что нет гарантии, что для любого интерфейса вы можете напрямую использовать другой интерфейс. Поставщик для интерфейса может быть дочерним по отношению к классу. – Jonathan

ответ

0

1: Попробуйте это:

IAttrList Attr(AttrList.GetItem(Some_Attribute)); 

2: Если вы можете извлечь IUnknown* или IDispatch* из AttrList.GetItem(Some_Attribute) использовать его как это:

IAttrList Attr((Extracted IUnknown* or IDispatch*)); 

Поскольку конструктор IAttrList подобен IAttrList(IDispatch *subobject = 0, QAxObject *parent = 0) : QAxObject((IUnknown*)subobject, parent)

Надеюсь, это поможет вам, у меня была аналогичная проблема с использованием Qt, и первый код помог я решаю это.