Я начинаю очень нервничать с моей проблемой, я попытаюсь описать свою потребность, надеюсь, что кто-то поймет. Представьте, что у меня есть проект, который генерирует один исполняемый файл и некоторые плагины (загружаемая библиотека времени исполнения). Этот исполняемый файл является своего рода демоном/службой, который вначале ищет подходящие плагины. Таким образом, эти плагины должны предоставлять некоторый абстрактный уровень связи. Я просмотрел Qt Doc и нашел класс QPluginLoader, который должен обеспечивать загрузку интерфейса с .so, но интерфейс не может иметь сигнал/слот, должен быть чистым виртуальным. Поэтому я подумал о том, что будет возвращать объекты на основе QObject ...QObject factory in Qt Plugin (не создатель)
!!! Пожалуйста, не пугайтесь, его только 2 интерфейсов и 2 реализаций :)
Мой макет проекта и содержание:
./Daemon/Interfaces/PluginInterface.h
#include <QObject>
#include "PluginInterface.h"
class PluginInterface {
public:
virtual ~PluginInterface() = 0;
virtual ProtocolInterface* getInterface() = 0;
virtual int getPluginId() const = 0;
};
Q_DECLARE_INTERFACE(PluginInterface, "com.porta.protocol.PluginInterface/1.0")
./Daemon/Interfaces/ ProtocolInterface.h
#include <QObject>
#include "turnstile.h"
class ProtocolInterface : public QObject {
Q_OBJECT
public:
ProtocolInterface(QObject *parent = 0) : QObject(parent) {}
virtual QWidget* getConfigureGUI() = 0;
virtual void init() = 0;
virtual void start() = 0;
signals:
void someSignal();
};
./Daemon/ProtocolHander.cpp (& ч) < - просто плагин загрузки и какая-то логика
./Daemon.pro
QT += core gui
TARGET = porta_daemon
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp \
protocolhandler.cpp
HEADERS += protocolhandler.h \
Interfaces/protocolinterface.h \
Interfaces/protocolloader.h \
Interfaces/turnstile.h
./Plugins/Dummy/DummyPluginInterface.h
#include "protocolloader.h"
#include <QObject>
class DummyPluginInterface : public QObject, PluginInterface {
Q_OBJECT
Q_INTERFACES(PluginInterface)
public:
ProtocolInterface* getInterface();
int getPluginId() const;
};
./Plugins/Dummy/DummyPluginInterface.cpp
#include "DummyPluginInterface.h"
#include "DummyProtocolInterface.h"
ProtocolInterface *DummyPluginInterface::getInterface() {
return new DummyProtocolInterface();
}
int DummyPluginInterface::getPluginId() const {
return 1;
}
Q_EXPORT_PLUGIN2(dummyplugin, DummyPluginInterface)
./ Плагины/Dummy/DummyProtocolInterface.h
#include "protocolinterface.h"
#include <QObject>
class DummyProtocolInterface : public ProtocolInterface {
public:
void init();
QWidget* getConfigureGUI();
void start();
int getPluginId() { return 1; }
};
./Plugins/Dummy/DummyProtocolInterface.cpp
#include "DummyProtocolInterface.h"
QWidget* DummyProtocolInterface::getConfigureGUI() {
return 0;
}
void DummyProtocolInterface::start() {
}
void DummyProtocolInterface::init() {
emit someSignal(); /// !!! this is important for me
}
./Plugins/Dummy/Dummy.pro
TEMPLATE = lib
CONFIG += plugin
QT += network
INCLUDEPATH += ../../Daemon/Interfaces/
HEADERS += ****
SOURCES += ****
TARGET = *****
DESTDIR = *****
Мой promblem является то, что я получаю, связывающие ошибки или во время выполнения неразрешенные символы (в основном, из QObject), или мои сигналы не могут быть связаны ... ПротоколHandler должен быть тем, кто подключает сигналы/слоты.
Может ли кто-нибудь сказать мне, как сделать этот подход? Примеры Qt не охватывают такие мысли.
СПАСИБО!
Адам
Что связывающие ошибки? –
Например, этот ... "libdummyplugin.so: undefined symbol: _ZN17ProtocolInterface16staticMetaObjectE)" ... но мой коллега предложил мне разместить ProtocolInterface.h в HEADERS + = раздел файла Plugin.pro ... после того, как я пришел домой от работы, я попробую это –
Да, он прав, это означает, что вам не хватает метаданных из класса ProtocolInterface. –