尝试在C++/Qt中创建一个插件系统

6
我是一个基于任务的程序,需要有插件。任务需要具有可轻松编辑的属性,我认为可以使用Qt的元对象编译器反射功能来实现这一点(我可能错了,但我应该能够将其放入QtPropertyBrowser中?)
所以这是基础:
class Task : public QObject
{
Q_OBJECT
public:
    explicit Task(QObject *parent = 0) : QObject(parent){}

    virtual void run() = 0;

signals:
    void taskFinished(bool success = true);
}

然后一个插件可能有这个任务:
class PrinterTask : public Task
{
Q_OBJECT
public:
    explicit PrinterTask(QObject *parent = 0) : Task(parent) {}

    void run()
    {
        Printer::getInstance()->Print(this->getData());  // fictional
        emit taskFinished(true); 
    }

    inline const QString &getData() const;
    inline void setData(QString data);

Q_PROPERTY(QString data READ getData WRITE setData) // for reflection
}

简而言之,我想要做的是:
// load plugin
// find all the Tasks interface implementations in it
// have user able to choose a Task and edit its specific Q_PROPERTY's
// run the TASK

一个.dll有多个任务很重要,因为我想让它们与它们的模块相关联。比如,“FileTasks.dll”可以有删除文件、创建文件等任务。

Qt插件设置唯一的问题是我想在一个.dll模块中存储X数量的任务。据我所知,您只能每次加载一个接口(我可能错了?)。如果是这样,实现我想要的唯一可能的方法是创建一个基于字符串的键的FactoryInterface,返回对象(就像Qt的Plug-And-Paint示例中那样),这是一个可怕的样板,我想避免。

有人知道比Qt更清洁的C++插件架构来实现我的需求吗?

另外,我可以安全地假设Qt的反射功能将实现我想要的功能(即在分派之前使用QtPropertyBrowser编辑未知动态加载任务的属性)吗?

2个回答

8
听起来你已经认真考虑过这个问题了,这是很好的也是必要的。我无法评论Qt的具体情况,但请务必不要错过这些插件建议的关键点,特别是版本控制:插件架构 编辑: 上面的原始链接出现错误(已添加了8年...)。The Wayback Machine有一份拷贝

很棒的阅读材料,而且还有一个示例框架解决方案。基本上它说你只需要一个更智能的工厂系统来避免字符串键给你带来的样板文件,我想我可能过度思考了问题。如果我能集成它,这可能会解决我的问题。谢谢。 - Pirate for Profit
链接已经失效了。有人知道这个的更新链接吗? - Adrian
1
@Kobe:我添加了那篇文章的Wayback Machine副本。感谢您让我们知道它出了问题。 - Johann Gerell

5
你有避免使用Qt内置的插件框架的任何原因吗?
例如这里
编辑:抱歉,我错过了

据我所知,每个插件只能加载一个接口

之前。 插入并绘制示例显示您可以在一个插件中实现许多接口。 我对你所说的基于字符串的工厂感到困惑,该示例在加载插件后使用QObjects,slots和signals。 字符串仅用于在帮助菜单中显示插件名称。

我的意思是一种简单地加载许多继承同一个接口的类的插件方式。也许我有些困惑,但看起来好像你只能加载每个接口类型的一个?我认为必须使用一种变通方法。 - Pirate for Profit
也许我也有点困惑,您想从一个dll中加载多个插件吗?首先,除了less文件之外,为什么要这样做?其次,如果是这种情况,那么是的,您是正确的。每个dll只是一个插件,但每个插件可以实现多个接口。如果您想要单个dll的唯一原因是为了less文件,我强烈建议您不要这样做。更小的编译单元会导致更快的重新编译时间和更容易的测试。 - Adam W
每个插件一个DLL对于开发者和用户来说都更简单。完全同意Adam的观点。 - Conrad Jones

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接