L
L
lightalex2017-04-27 22:35:20
C++ / C#
lightalex, 2017-04-27 22:35:20

How to dynamically link libraries?

Hello everyone
The question arose, is it possible to dynamically link libraries in C ++ without knowing either the name or the path where the library will be located when writing the program? Knowing just that in the connected library there is a guaranteed central function (let's say main)
The task is that there is a program that works 24/7 and different libraries are connected to it, each with its own task. Sometimes it becomes necessary to slightly rewrite the code in the library. And you need to update the library without stopping the program. That is, a request comes to the program, it disables the specified lib, loads a new one and turns it on.
Is this possible to implement?
If so, please help with a link to materials and articles.
Thank you in advance for your participation :)
PS Development environment - MVS

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Ariox41, 2017-04-28
@lightalex

Take a look at boost::DLL
Allows you to dynamically load libraries, automatically counts references to loaded functions and unloads the library when all references are destroyed (be aware that if you get some data manually, it must be destroyed before the library is unloaded , because the library can't count references to your data).
There are many examples in the documentation, no special problems should arise.
An example from the documentation, just in case:

// 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() {}
};

Plugin implementation:
// 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

Actually, loading the library:
#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;
}

Conclusion:
Loading the plugin
Constructing my_plugin_sum
plugin->calculate(1.5, 1.5) call:  3
Destructing my_plugin_sum ;o)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question