【发布时间】:2017-05-16 10:00:53
【问题描述】:
我正在尝试使用 COM 对象,但在转换返回的函数值时遇到问题。我正在使用 Qt 5.7.0,我使用 dumpcpp 工具获得了 COM 对象的 .h 和 .cpp 文件。
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 对象的功能,除非它会返回一个指示的类指针。在这种情况下,de 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 指针似乎无效,因为尝试使用它时出现分段错误。
我不知道问题可能出在哪里,有什么问题吗?提前致谢。
【问题讨论】:
-
你应该在 IUnkown 上使用 QueryInterface 来询问你想要的接口。您不应该在 COM 中假设 IUnkown 可以直接转换为您想要的类型。
-
感谢您的回答,我不确定查询接口的使用。你指的是这样的想法吗? QVariant var = AttrList.GetItem (some_attribute); AttrList.queryInterface (some_UUID, (void **) var);如何获得 UUID 到 IAttrList 类?再次感谢。
-
不幸的是我没有或没有使用 Qt...所以我无法回答图书馆的具体情况。 UUID 是一个数字,如果您进行了 typelib 导入,通常会有一个常数。 queryInterface 应该在作为返回值收到的 IUnkown 对象上完成。这要求解析到该接口的类的指针。否则当接口不支持时会返回错误。为什么要这样做是因为不能保证任何接口都可以直接转换为另一个接口。接口的提供者可以是该类的子类。
-
我用工具dumpcpp获得的类,并定义了任何UUID。我已经用 SetControl 方法分配了一个,我调用了 QueryInterface 过程:
HRESULT Hr = AttrList.QueryIntrface (IID_AttrList, (void **) & var);但是这总是返回,0x80004001 **E_NOTIMPL**令人沮丧的是,在 .Net 中通过简单的分配实现的东西可能让我非常头疼。再次感谢。 -
未实现意味着它确实有这个接口。这可能意味着您认为不是 AttrList。实际上,当我重新阅读您的描述时,我看到您得到了一个“QVariant”,它可能与 COM 变体类似。因此,您可能必须转换为 QVariant,然后尝试从中获取价值。查看 QVariant 在线文档并没有显示 ArrayList 类型...也许您需要 QList?有一个 type() 会告诉你变体持有什么。