Ещё один С++ plugin framework

Вступление

Кого не посещала, пользуясь open-source библиотеками, мысль: «Спасибо этим парням за эту крутую либу! Когда-нибудь и я напишу что-нибудь стоящее, и выложу это в public, чтоб другие пользовались!»

Да всех! Или не ?..

С приходом стандарта C++17, наши хотелки решаются гораздо быстрее и изящнее, нужно лишь захотеть воплотить в жизнь задуманную идею, и уметь применять на деле вкусняшки, которыми нас балуют ребята из WG21.
Не слишком ли много и? Хотя: #мыжпрограммисты, для нас это норма )) ...

Предыстория

Тема плагинов довольно интересная, потому что позволяет вносить новый функционал в Программное Обеспечение (ПО) без внесения изменений в ядро программы, но при этом должен быть продуман и написан интерфейс для взаимодействия: ПО <-> Менеджер Плагинов <-> Плагины.

У меня имеется опыт (неудачный) собеседования в фирму, в которой имеется своя плагиновая система для embedded систем, из-за запутанности архитектуры которой я завалил тестовое задание. Там много макросов внутри базовых классов от которых наследуется, и много всякого такого, что делает будни программиста серыми в моменты использования подобных решений…

В один из моментов самообразования, и прочтения статей по C++17 и было принято решение закрепить почерпнутые знания при написании системы плагинов, которая бы была понятной и легкой в использовании.

Насколько плохо или хорошо у меня это получилось — судить вам, дорогие хабровчане…

Обзор

Возможности библиотеки

  • Плагины как сервисы (выполняются в отдельных трэдах)
  • Автоматическая выгрузка неиспользуемых плагинов

Плюсы

  • Простота использования
  • Асинхронное выполнение задач
  • Header-only дизайн

Минусы

  • Если вносится в систему новый плагин, то он должен быть скомпилирован той же версией компилятора что и менеджер его загружающий (также как и libstdc++) для совместимости ABI
  • Постоянные кэсты из std::any к используемым типам?
  • Проверка фьючерсов на валидность?

Создание плагина

class myplugin : public micro::iplugin { public:   myplugin(float ver, const std::string& nm):micro::iplugin(ver, nm) {     // регистрация лямбды в плагине     subscribe<2>("sum2",       [](std::any a, std::any b)->std::any{ return std::any_cast<int>(a) + std::any_cast<int>(b); },       "справка к функции"     );   } };

Загрузка плагина

std::shared_ptr<micro::plugins> manager = micro::plugins::get(); std::shared_ptr<micro::iplugin> myplugin = manager->get_plugin("myplugin");  if (myplugin && myplugin->has<2>("sum2")) {   std::shared_future<std::any> result = myplugin->run<2>("sum2", 25, 25);   result.wait();    std::cout << std::any_cast<int>(result.get()) << std::endl; }

Более детальные примеры смотрите на странице проекта

Вместо заключения

Мне очень приятно читать познавательные статьи на Хабре по С++ (да и не только по C++),
надеюсь и вам эта статья будет интересна и хоть сколько-нибудь познавательна.

По моему скромному мнению, либу можно юзать в проде, пусть взглянут более авторитетные C++’ки и скажут своё слово, исходники хорошо документированы и их не много, — порядка 1000 строк.

Ссылка на проект

microplugins

FavoriteLoadingДобавить в избранное
Posted in Без рубрики

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *