QtPlugin无法加载库
QtPlugin Cannot Load Library
我在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)
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
TEMPLATE = subdirs
SUBDIRS +=
app
counter
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
#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
#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
#include "base.h"
Base::Base(QObject *parent) :
QObject(parent)
{
}
Base::~Base()
{
}
QString Base::name()
{
return name_;
}
#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();
}
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
}
#ifndef COUNTER_H
#define COUNTER_H
#include <QObject>
#include "base.h"
class Counter : public Base {
Q_OBJECT
public:
Counter();
};
#endif // COUNTER_H
#include "counter.h"
Counter::Counter()
{
name_ = "Counter";
}
#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
#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
}
相关文章:
- std::原子加载和存储都需要吗
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 为什么加载SDF会导致Mobilizer创建闭环错误
- C++atioglxx.pdb未加载错误glBufferData OpenGL
- 如何使用tinyxml2从XML加载父实体和子实体
- 如何在C++中使用pybind11加载一个pickle python列表
- 系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
- 当我尝试加载内核模块时,如何修复C++中的这个 malloc() 错误?
- 树莓上的 Libtorch 无法加载 pt 文件,但在 ubuntu 上工作
- Python ctypes:不会按预期加载 dll
- 为什么会出现 gettnig 运行时错误:加载类型为"_Bit_type"(stl_bvector.h) 的空指针?
- 我的程序有一个保存配置文件的GUI,如何双击此配置文件以直接加载带有配置数据的GUI?
- 保存/加载大量短数组到二进制文件
- 使用 SDL2 和SDL_image C++加载图像
- 无法使用加载库卸载注入的 dll (C++)
- 是否有原子加载非原子值的函数?
- 将 bmp 文件加载到 TSpeedButton 中
- 如何使用Qt 3D库加载和显示搅拌机.obj源文件场景
- QtPlugin无法加载库