LinuxでGCCを使用してQt4.8.3を使用しています。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)
編集:デバッグモードでコンパイルした後のエラーメッセージを更新しました。
編集: BaseNodeクラスをエクスポート/インポートしようとしましたが、これも機能しませんでした。それが完全に間違っているのか、それとも間違っているのかわかりません。Baseクラスに次の変更が加えられました(BASE_LIBRARYがapp.proファイルのDEFINESに追加されました)。
#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 {