QtPlugin无法加载库

QtPlugin Cannot Load Library

本文关键字:加载 QtPlugin      更新时间:2023-10-16

我在Linux上使用Qt 4.8.3与GCC。我试图创建一个模块化的应用程序与QtPlugin。应用程序描述了一些基本功能,然后一系列插件将提供所有独特的功能。每个插件都使用一个工厂来提供一个类的多个实例,并由工厂类和要提供的类组成。

目前,应用程序正在编译,但没有执行,我得到错误,如Cannot load library ~: (~: undefined symbol: _ZTI8Base16staticMetaObjectE)。我不知道如何修复这个错误。删除所有提到的Base解决了问题,但实例需要从该类派生,所以我认为这不会起作用。

我已经包含了下面的项目结构与可执行文件和一个插件(他们目前都是相同的,有同样的问题)。

非常感谢您的帮助。

目录结构
main_project
+- main_project.pro
+- app/
| +- app.pro
| +- main.cpp
| +- factoryinterface.h
| +- base.h
| +- base.cpp
|
+- counter/
  +- counter.pro
  +- counter.h
  +- counterfactory.cpp
  +- counterfactory.h
  +- counter.cpp

main_project.pro

TEMPLATE = subdirs
SUBDIRS += 
    app 
    counter

app.pro

QT       += core
QT       -= gui
DESTDIR = ../
TARGET = app_exec
CONFIG   += console
CONFIG   -= app_bundle
TEMPLATE = app
SOURCES += main.cpp 
    base.cpp
HEADERS += 
    base.h 
    factoryinterface.h

factoryinterface.h

#ifndef FACTORYINTERFACE_H
#define FACTORYINTERFACE_H
#include <QtPlugin>
#include "base.h"
class FactoryInterface {
public:
    virtual ~FactoryInterface() {}
    virtual Base *get() = 0;
    virtual QString name() = 0;
};
Q_DECLARE_INTERFACE(FactoryInterface,
                    "com.example.FactoryInterface/1.0")
#endif // FACTORYINTERFACE_H

base.h

#ifndef BASE_H
#define BASE_H
#include <QObject>
#include <QString>
#include <QStringList>
#include <QHash>
class Base : public QObject {
    Q_OBJECT
public:
    Base(QObject *parent = 0);
    virtual ~Base();
    virtual QString name();
signals:
public slots:
protected:
    QString name_;
};
#endif // BASE_H

base.cpp

#include "base.h"
Base::Base(QObject *parent) :
    QObject(parent)
{
}
Base::~Base()
{
}
QString Base::name()
{
    return name_;
}

main.cpp

#include <QtCore/QCoreApplication>
#include <QDir>
#include <QPluginLoader>
#include <QDebug>
#include "factoryinterface.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QDir pluginDir(a.applicationDirPath());
    pluginDir.cd("plugins");
    foreach(QString filename, pluginDir.entryList(QDir::Files))
    {
        QPluginLoader loader(pluginDir.absoluteFilePath(filename));
        QObject *plugin = loader.instance();
        if (plugin)
        {
            FactoryInterface *i = qobject_cast<FactoryInterface*>(plugin);
            if (i)
            {
                qDebug() << " :" << i->name();
            }
        } else {
            qDebug() << loader.errorString();
        }
    }
    return a.exec();
}

counter.pro

QT       -= gui
CONFIG   += plugin
TARGET = $$qtLibraryTarget(counter)
TEMPLATE = lib
DEFINES += COUNTER_LIBRARY
SOURCES += counter.cpp 
    counterfactory.cpp
HEADERS += counter.h 
    counterfactory.h
INCLUDEPATH += ../app
DESTDIR = ../plugins
symbian {
    MMP_RULES += EXPORTUNFROZEN
    TARGET.UID3 = 0xE5B38B75
    TARGET.CAPABILITY = 
    TARGET.EPOCALLOWDLLDATA = 1
    addFiles.sources = counter.dll
    addFiles.path = !:/sys/bin
    DEPLOYMENT += addFiles
}
unix:!symbian {
    maemo5 {
        target.path = /opt/usr/lib
    } else {
        target.path = /usr/lib
    }
    INSTALLS += target
}

counter.h

#ifndef COUNTER_H
#define COUNTER_H
#include <QObject>
#include "base.h"
class Counter : public Base {
    Q_OBJECT
public:
    Counter();
};
#endif // COUNTER_H

counter.cpp

#include "counter.h"

Counter::Counter()
{
    name_ = "Counter";
}

counterfactory.h

#ifndef COUNTER_H
#define COUNTER_H
#include <QObject>
#include "factoryinterface.h"
#include "base.h"
#include "counter.h"
class CounterFactory : public QObject, public FactoryInterface
{
    Q_OBJECT
    Q_INTERFACES(FactoryInterface)
public:
    explicit CounterFactory(QObject *parent = 0);
    Base *get();
    QString name();
signals:
public slots:
};
#endif // COUNTER_H

counterfactory.cpp

#include "counterfactory.h"

CounterFactory::CounterFactory(QObject *parent) :
    QObject(parent)
{
}
Base *CounterFactory::get()
{
    return new Counter;
}
QString CounterFactory::name()
{
    return "Counter";
}
Q_EXPORT_PLUGIN2(counter, CounterFactory)

Edit:更新Debug模式下编译后的错误信息。

编辑:我尝试导出/导入BaseNode类,但这也不起作用。我不确定这是完全错误的,还是我做错了。对基类做了以下更改(BASE_LIBRARY被添加到app.pro文件中的定义中):

#include <QtCore/qglobal.h>
#if defined(BASE_LIBRARY)
#  define BASESHARED_EXPORT Q_DECL_EXPORT
#else
#  define BASESHARED_EXPORT Q_DECL_IMPORT
#endif
class BASESHARED_EXPORT Base : public QObject {

解决方案是将Base类添加到计数器中。支持文件。我已经列出了完整更新的计数器。但唯一的变化是增加了header和SOURCES。

counter.pro

QT       -= gui
CONFIG   += plugin
TARGET = $$qtLibraryTarget(counter)
TEMPLATE = lib
DEFINES += COUNTER_LIBRARY
SOURCES += counter.cpp 
    counterfactory.cpp 
    ../app/base.cpp
HEADERS += counter.h 
    counterfactory.h 
    ../app/base.h
INCLUDEPATH += ../app
DESTDIR = ../plugins
symbian {
    MMP_RULES += EXPORTUNFROZEN
    TARGET.UID3 = 0xE5B38B75
    TARGET.CAPABILITY = 
    TARGET.EPOCALLOWDLLDATA = 1
    addFiles.sources = counter.dll
    addFiles.path = !:/sys/bin
    DEPLOYMENT += addFiles
}
unix:!symbian {
    maemo5 {
        target.path = /opt/usr/lib
    } else {
        target.path = /usr/lib
    }
    INSTALLS += target
}