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

时间:2014-01-28 11:33:58

标签: c++ qt plugins

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

因此,我使用名为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();
}

1 个答案:

答案 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);

隐式赋值会将它强制转换为正确的基类。

注意:如果您有其他继承树,则必须首先检查演员表是否成功。