У меня есть приложение QT5, которое можно расширить с помощью плагинов приложений с помощью низкоуровневого API плагинов QT5. Пока я могу загрузить / запустить / остановить / выгрузить плагин. Я также могу подключить пользовательский интерфейс плагина к приложению.
Точка, в которой я сейчас отказываюсь, - это взаимосвязь слотов и сигналов плагинов. Идея, лежащая в основе всего этого, заключается в том, что некоторые плагины должны обеспечивать некоторую функциональность (услугу), которая используется другими плагинами.
В качестве примера я разработал класс «Задача», который содержит всю информацию, необходимую для специальной службы. Класс является разделяемой библиотекой, поэтому каждый подключаемый модуль может интегрировать эту функциональность. Экземпляр «Задача» предоставляет два сигнала «успешно» и «не удалось», которые связаны со слотами, предоставленными потребителем услуг. Сигналы имеют указатель на задачу, которая испускает сигнал. Таким образом, «ссылка» на экземпляр предоставляется сама по себе.
class Task : public QObject
{
public:
explicit Task( // parameters of task
);
~Task();
// methods of Task
signals:
void succeeded(Task *task);
void failed(Task *task);
private:
// some private stuff
}
Таким образом, путь к потребителю, похоже, готов. Теперь мне нужно передать объект «задача» сервис-провайдеру, который находится в другом плагине.
Моя идея заключалась в разработке другого класса «Сервис», который содержит все слоты, предоставляемые плагином.
class PluginService
{
public:
explicit PluginService(QObject *service);
~PluginService();
// methods for requesting a service and it's provided slots
QObject *service();
QMetaMethod *slot(const QString &slot = "");
// method to setup the slots for a service
void addSlot(const QString& name = "", QMetaMethod *slot = nullptr);
private:
QObject *mService;
QMap<QString, QMetaMethod *> *mSlots;
};
С этим классом я хочу иметь список служб и предоставленных им слотов. Это позволяет менеджеру службы в основном приложении связывать поставщиков услуг и потребителей вместе после загрузки всех плагинов. Мета-информация для связи предоставляется. json -файлами плагинов.
I для получения слотов, как показано ниже в плагине service-provder-plugin:
// this code is already working as expected
TaskManager *manager = mForm->taskManager();
manager->moveToThread(&mThread);
connect(this, &PluginCmdBase::execute, manager, &TaskManager::onExecute);
connect(this, &PluginCmdBase::abort, manager, &TaskManager::onAbort);
mThread.start();
// here my problems start
mServices = new std::vector<pluginbase::PluginService *>();
pluginbase::PluginService *service = new pluginbase::PluginService(manager);
// here should the "magic" happen, but I fail to get a proper cast
service->addSlot("onExecute", &TaskManager::onExecute);
service->addSlot("onAbort", &TaskManager::onAbort);
mServices->push_back(service);
"addSlot" явно не работает . Я пробовал разные приведения, но не работал. Я всегда получаю ошибки компилятора, такие как:
Error: no matching function for call to 'pluginbase::PluginService::addSlot(const char [10], void (plugincmd::TaskManager::*)(plugincmd::Task*))'
service->addSlot("onExecute", &TaskManager::onExecute);
^
Я пытался с QMetaMethod, потому что он используется в методе "QObject :: connect ()", но я открыт, чтобы изменить это при необходимости.
Однако как правильно получить «ссылку» на слот поставщика услуг, чтобы я мог использовать его в методе «Object :: connect ()»?