我想编写一个包含多个插件的应用程序。我的想法是插件本身始终只是一个工厂,然后可以创建所需的对象。
因此,我使用名为 create 的纯虚拟方法为名为 AbstractFactoryPlugin 的插件工厂创建了一个接口(interface)。因为我想拥有几个具有相同接口(interface)的不同插件(工厂),所以我不能将 Q_DECLARE_INTERFACE 宏放在 AbstractFactoryPlugin 头文件中。
因此,对于示例插件,我创建了一个继承自 AbstractFactoryPlugin 的接口(interface),称为 IMyObjectFactoryPlugin,并使用 DECLARE 宏声明了该接口(interface)。此外,MyObjectFactoryPlugin 继承自 QObject 和 IMyObjectFactoryPlugin。
但是当我加载插件并调用创建函数时,MyObjectFactoryPlugin 的创建函数似乎从未被调用过。我做错了什么?
非常感谢。
源代码:
#ifndef ABSTRACTPLUGINFACTORY_H
#define ABSTRACTPLUGINFACTORY_H
#include "IAnObject.h"
class AbstractFactoryPlugin
{
public:
virtual ~AbstractFactoryPlugin() {}
virtual IAnObject *create(QObject *parent) = 0;
};
#endif // ABSTRACTPLUGINFACTORY_H
#ifndef IMYOBJECTFACTORYPLUGIN_H
#define IMYOBJECTFACTORYPLUGIN_H
#include "AbstractFactoryPlugin.h"
#include <QtPlugin>
class IMyObjectFactoryPlugin : public AbstractFactoryPlugin
{
public:
virtual ~IMyObjectFactoryPlugin() {}
};
QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(IMyObjectFactoryPlugin,
"org.MyObjectFactoryPlugin");
QT_END_NAMESPACE
#endif // IMYOBJECTFACTORYPLUGIN_H
#ifndef MYOBJECTPLUGIN_H
#define MYOBJECTPLUGIN_H
#include <QtPlugin>
#include "IMyObjectFactoryPlugin.h"
#include "AbstractFactoryPlugin.h"
class MyObjectFactoryPlugin : public QObject, IMyObjectFactoryPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.MyObjectFactoryPlugin" )
Q_INTERFACES(IMyObjectFactoryPlugin)
public:
MyObjectFactoryPlugin(QObject *parent = 0);
IAnObject *create(QObject *parent);
};
#endif // MYOBJECTPLUGIN_H
#include "MyObject.h"
#include "MyObjectFactoryPlugin.h"
#include <QDebug>
MyObjectFactoryPlugin::MyObjectFactoryPlugin(QObject *parent) :
QObject(parent)
{
}
IAnObject *MyObjectFactoryPlugin::create(QObject *parent)
{
qDebug() << Q_FUNC_INFO << "was called";
return new MyObject();
}
#ifndef IANOBJECT_H
#define IANOBJECT_H
class IAnObject
{
public:
IAnObject() {isInitialized = false;}
virtual ~IAnObject() {}
virtual bool initialize() = 0;
protected:
bool isInitialized;
};
#endif // IANOBJECT_H
#include "IAnObject.h"
#ifndef MYOBJECT_H
#define MYOBJECT_H
class MyObject : public IAnObject
{
public:
MyObject();
bool initialize();
};
#endif // MYOBJECT_H
#include "MyObject.h"
MyObject::MyObject()
{
}
bool MyObject::initialize()
{
return true;
}
#include <QCoreApplication>
#include <QDir>
#include <QPluginLoader>
#include <QDebug>
#include <E:/QtProjects/_test_PlugIn/MyPlugin/AbstractFactoryPlugin.h>
#include <E:/QtProjects/_test_PlugIn/MyPlugin/IAnObject.h>
#include <E:/QtProjects/_test_PlugIn/MyPlugin/IMyObjectFactoryPlugin.h>
IAnObject *loadPlugin()
{
QDir dir(QCoreApplication::applicationDirPath());
qDebug() << dir;
foreach(QString fileName, dir.entryList(QDir::Files))
{
QPluginLoader pluginLoader(dir.absoluteFilePath(fileName));
QObject *plugin = pluginLoader.instance();
qDebug() << fileName;
if(plugin)
{
qDebug() << "##### Plugin load ok #####";
AbstractFactoryPlugin *abstractFactoryPlugin = reinterpret_cast<AbstractFactoryPlugin *>(plugin);
return abstractFactoryPlugin->create(NULL);
}
}
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "loadPlugin:" << loadPlugin();
return a.exec();
}
最佳答案
任何 Qt5 插件都必须继承自 QObject,如果您希望基类独立于 QObject,则必须创建一个同时继承 AbstractFactoryPlugin 和 QObject 的中间类(我们称之为 AbstractMyObjectFactoryPlugin)。
#ifndef ABSTRACTMYOBJECTFACTORYPLUGIN_H
#define ABSTRACTMYOBJECTFACTORYPLUGIN_H
#include "AbstractFactoryPlugin.h"
class AbstractMyObjectFactoryPlugin : public QObject, public AbstractFactoryPlugin
{
Q_OBJECT
public:
AbstractMyObjectFactoryPlugin(QObject *parent = 0) : QObject(parent) { }
virtual ~AbstractMyObjectFactoryPlugin() { }
};
Q_DECLARE_INTERFACE(AbstractMyObjectFactoryPlugin,
"org.AbstractFactoryPlugin");
#endif // ABSTRACTMYOBJECTFACTORYPLUGIN_H
要创建插件,您必须继承此类并重写 create() 方法:
class MyObjectFactoryPlugin : public AbstractMyObjectFactoryPlugin
{
Q_OBJECT
Q_INTERFACES(AbstractMyObjectFactoryPlugin)
Q_PLUGIN_METADATA(IID "org.MyObjectFactoryPlugin" FILE "MyObjectFactoryPlugin.json")
public:
MyObjectFactoryPlugin(QObject* parent = 0) : AbstractMyObjectFactoryPlugin(parent) { }
virtual IAnObject *create(QObject *parent);
virtual ~MyObjectFactoryPlugin() { }
};
要将加载的插件(QObject)安全地转换为 AbstractFactoryPlugin,您必须先将其转换为中间类。
AbstractFactoryPlugin * objectFactoryPlugin = qobject_cast< AbstractMyObjectFactoryPlugin * >(plugin);
隐式赋值会将其强制转换为正确的基类。
注意:如果您有其他继承树,则必须先检查转换是否成功。
关于c++ - 从 (Qt) 插件调用函数失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21404527/