c++ - 从 (Qt) 插件调用函数失败

标签 c++ qt plugins

我想编写一个包含多个插件的应用程序。我的想法是插件本身始终只是一个工厂,然后可以创建所需的对象。

因此,我使用名为 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/

相关文章:

c++ - 在屏幕上打印符号\作为文本

c++ - 为什么不是来自 std::array 双向/随机访问的 ConstexprIterator?

javascript - JQPlot 插件大小

C++ 数组存储错误的值

c++ - 在运行时生成机器指令的世界代码?

qt - 如何在 QSlider 中直接跳转而不损害性能

qt - 透明QWidget/QScrollArea背景样式设置无效

c++ - Qt 拆分器禁用

ruby-on-rails - http ://updatesite. ruby​​people.org/release 不是有效的存储库

node.js - SVGO - 添加插件