【问题标题】:Resource will not be loaded from every plugin in a multiple plugin application不会从多插件应用程序中的每个插件加载资源
【发布时间】:2014-04-25 13:23:58
【问题描述】:

我有一个基本上是插件管理器的应用程序。该应用程序应该能够处理任意数量的具有相同界面但行为不同的插件。

为了实现这一点,插件具有这样的类层次结构:

在这个最小的例子中,每个插件只有两个方法:getName,它返回一个硬编码的字符串,geId,它返回一个存储在文本文件中的字符串,该文本文件将被编译到每个插件的资源文件中。

问题是:每个插件都返回其硬编码的名称。但返回的 Id 是 both 情况下的 first 插件的 Id(见输出)。

这是为什么呢?这是代码和应用程​​序输出:

应用程序输出

############# Plugin load ok #############
"Plugin01"
"p01"

############# Plugin load ok #############
"Plugin02"
"p01"
############# ready #############   

ma​​in.cpp

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QDir dir(QCoreApplication::applicationDirPath());

    foreach(QString fileName, dir.entryList(QDir::Files))
    {
        QPluginLoader pluginLoader(dir.absoluteFilePath(fileName));
        QObject *plugin = pluginLoader.instance();
        if(plugin)
        {
            qDebug() << endl << "############# Plugin load ok #############";
            if(dynamic_cast<IPlugin* >(plugin))
            {
                qDebug() << dynamic_cast<IPlugin* >(plugin)->getName();
                qDebug() << dynamic_cast<IPlugin* >(plugin)->getId();
            }
        }
    }

    qDebug() << "############# ready #############";
    return a.exec();
}

IPlugin.h

class IPlugin : public QObject
{
    Q_OBJECT

    public:
        IPlugin(QObject *parent = 0) : QObject(parent) {}
        virtual ~IPlugin() {}
        virtual QString getId() = 0;
        virtual QString getName() = 0;
};

IPlugin01.h

class IPlugin01 : public IPlugin
{
    public:
        IPlugin01(QObject *parent) : IPlugin(parent) {}
        virtual ~IPlugin01() {}
};

QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(IPlugin01,
                    "Plugin01/0.1");
QT_END_NAMESPACE

Plugin01.h

class Plugin01 : public IPlugin01
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "Plugin01/0.1")
    Q_INTERFACES(IPlugin01)

    public:
        Plugin01(QObject *parent = 0);
        virtual QString getId();
        virtual QString getName();
};

Plugin01.cpp

Plugin01::Plugin01(QObject *parent) :
    IPlugin01(parent)
{

}

QString Plugin01::getId()
{
    QFile file(":/id.txt");

    if(file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        return file.readAll();
    }

    return "";
}

QString Plugin01::getName()
{
    return "Plugin01";
}

Plugin01的资源文件的id.txt

p01 

IPlugin02.h

class IPlugin02 : public IPlugin
{
    public:
        IPlugin02(QObject *parent) : IPlugin(parent) {}
        virtual ~IPlugin02() {}
};

QT_BEGIN_NAMESPACE
Q_DECLARE_INTERFACE(IPlugin02,
                    "Plugin02/0.1");
QT_END_NAMESPACE

Plugin02.h

class Plugin02 : public IPlugin02
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "Plugin02/0.1")
    Q_INTERFACES(IPlugin02)

    public:
        Plugin02(QObject *parent = 0);
        virtual QString getId();
        virtual QString getName();
};

Plugin02.cpp

Plugin02::Plugin02(QObject *parent) :
    IPlugin02(parent)
{

}

QString Plugin02::getId()
{
    QFile file(":/id.txt");

    if(file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        return file.readAll();
    }

    return "";
}


QString Plugin02::getName()
{
    return "Plugin02";
}

Plugin02的资源文件的id.txt

p02 

【问题讨论】:

    标签: c++ qt plugins


    【解决方案1】:

    资源路径是“全局的”,所以:/id.txt 不正确。您应该以其他方式设计您的资源结构。或者您应该手动加载资源。

    【讨论】:

    • 在Plugin01的资源文件中添加Plugin01前缀,在Plugin02的资源文件中添加Plugin02前缀解决了这个问题。只是好奇:“手动加载资源”是什么意思?
    • 我不确定这是否可行,但我认为 Qt 可以直接从二进制文件加载资源。请参阅QResource 类。我有点迷茫,因为我总是把资源作为外部二进制文件,所以不用重新编译代码就可以更新rcc文件(命令行是rcc -binary myresource.qrc -o myresource.rcc)。
    猜你喜欢
    • 1970-01-01
    • 2010-10-28
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多