C++ 从(Qt)插件调用函数失败
我想写一个由几个插件组成的应用程序。我的想法是插件本身总是一个工厂,然后可以创建所需的对象 因此,我为pluginfactory创建了一个名为AbstractFactoryPlugin的接口,并使用了一个名为create的纯虚拟方法。因为我希望有几个不同的插件(工厂)具有相同的接口,所以我不能将Q_DECLARE_interface宏放在AbstractFactoryPlugin头文件中 因此,对于一个示例插件,我创建了一个接口,该接口继承了AbstractFactoryPlugin,名为IMyObjectFactoryPlugin,并使用DECLARE宏声明了该接口。此外,MyObjectFactoryPlugin随后继承自QObject和IMyObjectFactoryPluginC++ 从(Qt)插件调用函数失败,c++,qt,plugins,C++,Qt,Plugins,我想写一个由几个插件组成的应用程序。我的想法是插件本身总是一个工厂,然后可以创建所需的对象 因此,我为pluginfactory创建了一个名为AbstractFactoryPlugin的接口,并使用了一个名为create的纯虚拟方法。因为我希望有几个不同的插件(工厂)具有相同的接口,所以我不能将Q_DECLARE_interface宏放在AbstractFactoryPlugin头文件中 因此,对于一个示例插件,我创建了一个接口,该接口继承了AbstractFactoryPlugin,名为IMy
#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函数时,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
#包括
#包括
#包括
#包括
#包括
#包括
#包括
IAnObject*loadPlugin()
{
QDir目录(QCoreApplication::applicationDirPath());
qDebug()任何Qt5插件都必须从QObject继承,如果希望基类独立于QObject,则必须创建一个继承AbstractFactoryPlugin和QObject的中间类(我们称之为AbstractMyObjectFactoryPlugin)
要创建插件,必须继承此类并重写create()方法:
要将加载的插件(QObject)安全地转换为AbstractFactoryPlugin,必须首先将其转换为中间类
AbstractFactoryPlugin * objectFactoryPlugin = qobject_cast< AbstractMyObjectFactoryPlugin * >(plugin);
AbstractFactoryPlugin*objectFactoryPlugin=qobject\u cast(插件);
隐式赋值将其强制转换为正确的基类
注意:如果您有其他继承树,您必须首先检查强制转换是否成功。您是否尝试了动态强制转换而不是重新解释强制转换?使用动态强制转换,应用程序将崩溃。使用调试器单步执行将导致异常:-------------------------------------异常触发-----------------推断r已停止,因为它触发了异常。在线程0中停止的原因:异常位于0xad1aad,代码:0xc0000005:读取访问冲突位于:0x0,标志=0x0(第一次机会).------------------------------------好的-----------------我忘了提到我正在使用Qt5。这就是为什么我没有使用Q_EXPORT_PLUGIN2,因为它已经被弃用了,但是使用了Q_PLUGIN_元数据宏。按照你的建议编辑我的代码是可行的。但是如果我ant希望从AbstractFactoryPlugin中派生更多插件,因为Q_DECLARE_接口宏的标识符相同?这就是为什么我在第一篇文章中写道,我试图避免这种情况:“因为我希望有几个不同的插件(工厂)具有相同的接口,所以我不能将Q_DE我更新了我的答案,这对我有效;尽管我不清楚这是否是你想要的。除了一件事之外,它有效。我从AbstractFactoryPlugin(例如AbstractOtherObjectFactoryPlugin)派生了另一个插件。如果加载了这个插件,这个cast可以工作,尽管它应该返回0:qobject_cast(插件)。将Q_DECLARE_接口的标识符从org.AbstractFactoryPlugin更改为org.AbstractMyObjectFactoryPlugin(用于AbstractMyObjectFactoryPlugin)和org.AbstractOtherObjectFactoryPlugin(用于AbstractOtherObjectFactoryPlugin),效果似乎更好。让每个接口都有自己的标识符不是更好吗?还是我做错了这样吗?您的所有插件都应该直接从AbstractMyObjectFactoryPlugin
继承,这实际上只是一个围绕AbstractFactoryPlugin
的QObject
,如果您想直接从AbstractFactoryPlugin
继承,您可以,但只能在同一个应用程序中(从AbstractFactoryPlugin
继承的插件根本不应该工作,但在测试中应该这样做,因为它们具有相同的签名)
#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();
}
#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
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() { }
};
AbstractFactoryPlugin * objectFactoryPlugin = qobject_cast< AbstractMyObjectFactoryPlugin * >(plugin);