我想编写一个包含多个插件的应用程序。我的想法是,插件本身只是一个工厂,然后可以创建所需的对象。
因此,我使用名为create的纯虚方法为pluginfactory创建了一个名为AbstractFactoryPlugin的接口。由于我希望有几个不同的插件(工厂)具有相同的接口,我无法将Q_DECLARE_INTERFACE宏放在AbstractFactoryPlugin头文件中。
因此,对于示例插件,我创建了一个接口,该接口继承自AbstractFactoryPlugin,名为IMyObjectFactoryPlugin,并使用DECLARE宏声明此接口。此外,MyObjectFactoryPlugin继承自QObject和IMyObjectFactoryPlugin。
但是当我加载插件并调用create函数时,似乎永远不会调用MyObjectFactoryPlugin的create函数。我做错了什么?
提前许多人。
源码:
#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();
}
答案 0 :(得分:1)
任何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);
隐式赋值会将它强制转换为正确的基类。
注意:如果您有其他继承树,则必须首先检查演员表是否成功。