我正在创建一组具有公共基类型的Qt插件。该应用程序加载一个插件,并对它提供的类进行分类,其基础是它所属的基本类型。
基本类型包含在静态库中,派生类型被构建到包含静态库的插件中,应用程序还链接到静态库。
简化后,如下所示:
静态库(通用)
class Base1 : public QObject {
Q_OBJECT
};
// Qt moc code generation:
// const QMetaObject Base1::staticMetaObject = {&QObject::staticMetaObject, /*etc*/};
class BasePlugin {
public:
virtual QObject* getObject()=0;
};共享库(插件)
class Derived1 : public Base1 {
Q_OBJECT
};
// Qt moc code generation:
// const QMetaObject Derived1::staticMetaObject = {&Base1::staticMetaObject, /*etc*/};
class Derived1Plugin: public QObject, public BasePlugin {
Q_OBJECT
public:
QObject* getObject() { return new Derived1; }
};应用程序
// setup plugin loader, load plugin
QObject* pluginObj = plugin.instance();
qDebug() << qobject_cast<Base1*>(pluginObj); // Displays 0x0
qDebug()
<< pluginObj->metaObject()->superClass() // Displays two different
<< &Base1::staticMetaObject; // pointer addresses经过一番研究后,本质上,Base1的元对象是Base1的静态数据成员,并被初始化了两次:一次在共享库中,一次在应用程序中。元对象Derived1::staticMetaObject在插件中初始化,指向在插件中初始化的Base1::staticMetaObject,应用程序中的名称Base1::staticMetaObject指向应用程序中初始化的元对象。MSVC和GCC都是如此。因此,Qt决定来自插件的派生类与来自应用程序的基类不兼容。
我的问题是:
Derived1继承了Base1发布于 2018-04-26 13:50:57
通过使用接口和接口宏,我得到了一种稍微复杂一些的工作方法。
关于扩展Qt应用程序的文档解释了这些宏的使用,但是并不是所有的插件机器都是动态强制转换工作所必需的。
class BaseInterface
{
public:
virtual ~BaseInterface() {}
virtual void foo() = 0;
};
Q_DECLARE_INTERFACE( BaseInterface, "org.example.BaseInterface" )
class Base1 : public QObject, public BaseInterface
{
Q_OBJECT
Q_INTERFACES( BaseInterface )
public:
virtual void foo() override {}
};现在您应该能够使用qobject_cast< BaseInterface* >(pluginObj)进行强制转换了。
理论上,您也可以将Base1本身定义为接口,并将Q_INTERFACES( Base1 )添加到Derived1的声明中,但我在尝试这样做时遇到了QTBUG-59460,而且这意味着继承Base1的每个类都必须记住添加该宏。
https://stackoverflow.com/questions/47930850
复制相似问题