lightalex
@lightalex

Как динамически подключать библиотеки?

Всем привет
Возник вопрос, возможно ли на C++ динамически подключать библиотеки не зная при написании программы ни имени, ни пути где будет находится библиотека? Зная только что в подключаемой библиотеке есть гарантированно центральная функция (допустим main)
Задача состоит в том что есть программа которая работает 24/7 и к ней подключаются разные библиотеки, каждая со своей задачей. Иногда возникает необходимость немного переписать код в библиотеке. И необходимо обновить библиотеку без остановки программы. То есть в программу приходит запрос, она отключает указанную либу, грузит новую и включает ее.
Такое возможно реализовать?
Если да, то помогите ссылкой на материалы и статьи
Заранее благодарю всех за участие :)
P.S. Среда разработки - MVS
  • Вопрос задан
  • 2123 просмотра
Решения вопроса 3
@Ariox41
Посмотрите в сторону boost::DLL

Позволяет динамически загружать библиотеки, автоматически подсчитывает ссылки на загруженные функции и выгружает библиотеку, когда все ссылки уничтожены (нужно учитывать, что если вы получаете какие-то данные вручную, их нужно уничтожить до того, как будет выгружена библиотека, поскольку библиотека не может подсчитывать ссылки на ваши данные).

В документации много примеров, особых проблем не должно возникнуть.

Пример из документации, на всякий случай:
// my_plugin_api.hpp
#include <string>

class my_plugin_api {
public:
   virtual std::string name() const = 0;
   virtual float calculate(float x, float y) = 0;

   virtual ~my_plugin_api() {}
};

Реализация плагина:
// my_plugin_sum.cpp
#include <boost/config.hpp> // for BOOST_SYMBOL_EXPORT
#include "../tutorial_common/my_plugin_api.hpp"

namespace my_namespace {

class my_plugin_sum : public my_plugin_api {
public:
    my_plugin_sum() {
        std::cout << "Constructing my_plugin_sum" << std::endl;
    }

    std::string name() const {
        return "sum";
    }

    float calculate(float x, float y) {
        return x + y;
    }

    ~my_plugin_sum() {
        std::cout << "Destructing my_plugin_sum ;o)" << std::endl;
    }
};

// Exporting `my_namespace::plugin` variable with alias name `plugin`
// (Has the same effect as `BOOST_DLL_ALIAS(my_namespace::plugin, plugin)`)
extern "C" BOOST_SYMBOL_EXPORT my_plugin_sum plugin;
my_plugin_sum plugin;

} // namespace my_namespace

Собственно, загрузка библиотеки:
#include <boost/dll/import.hpp> // for import_alias
#include <iostream>
#include "../tutorial_common/my_plugin_api.hpp"

namespace dll = boost::dll;

int main(int argc, char* argv[]) {

    boost::filesystem::path lib_path(argv[1]);          // argv[1] contains path to directory with our plugin library
    boost::shared_ptr<my_plugin_api> plugin;            // variable to hold a pointer to plugin variable
    std::cout << "Loading the plugin" << std::endl;

    plugin = dll::import<my_plugin_api>(          // type of imported symbol is located between `<` and `>`
        lib_path / "my_plugin_sum",                     // path to the library and library name
        "plugin",                                       // name of the symbol to import
        dll::load_mode::append_decorations              // makes `libmy_plugin_sum.so` or `my_plugin_sum.dll` from `my_plugin_sum`
    );

    std::cout << "plugin->calculate(1.5, 1.5) call:  " << plugin->calculate(1.5, 1.5) << std::endl;
}

Вывод:
Loading the plugin
Constructing my_plugin_sum
plugin->calculate(1.5, 1.5) call:  3
Destructing my_plugin_sum ;o)
Ответ написан
Комментировать
petermzg
@petermzg
Самый лучший программист
Ответ написан
Комментировать
@MarkusD Куратор тега C++
все время мелю чепуху :)
lightalex , да, описанное тобой поведение возможно.
У меня есть очень старый проект одной утилиты. Там практически реализовано необходимое тебе.

Вот самая основа, которая может тебя заинтересовать.
https://github.com/FrankStain/tex-conv/blob/master...
Это - функция обнаружения и загрузки всех плагинов в определенной директории.

https://github.com/FrankStain/tex-conv/blob/master...
Это - функция выгрузки плагинов.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы