项目作者: tocola

项目描述 :
Cross-platform Dynamic Library Loader for C++
高级语言: C++
项目地址: git://github.com/tocola/DyLib.git
创建时间: 2021-04-04T01:11:44Z
项目社区:https://github.com/tocola/DyLib

开源协议:MIT License

下载


dylib

version
license
cpp
ci

The goal of this C++ library is to load dynamic libraries (.so, .dll, .dylib) and access its C and C++ functions and global variables at runtime.

⭐ Don't forget to put a star if you like the project!

Compatibility

  • OS:
    Works on Linux, MacOS and Windows

  • Compilers:
    Works with GCC, Clang, MSVC and MinGW

Installation

Using a package manager

You can install dylib from vcpkg or conan center:

  1. vcpkg install dylib
  1. conan install --requires=dylib/3.0.1

Using CMake Fetch

You can also fetch dylib to your project using CMake:

  1. include(FetchContent)
  2. FetchContent_Declare(
  3. dylib
  4. GIT_REPOSITORY "https://github.com/martin-olivier/dylib"
  5. GIT_TAG "v3.0.1"
  6. )
  7. FetchContent_MakeAvailable(dylib)

Documentation

Constructor

The dylib::library class can load a dynamic library from a relative or a full path:

  1. // Load "foo" library from relative path "./plugins"
  2. dylib::library lib("./plugins/libfoo.so");
  3. // Load "foo" library from full path "/lib"
  4. dylib::library lib("/lib/libfoo.so");

The dylib::library class can add filename decorations to the library name.
You can use dylib::decorations::os_default() to add default OS decorations to the library name.
You can also use dylib::decorations to add custom decorations to the library name.

  1. // No decorations added
  2. // Windows -> "foo.lib"
  3. // MacOS -> "foo.lib"
  4. // Linux -> "foo.lib"
  5. dylib::library lib("./foo.lib");
  6. // Default OS decorations added
  7. // Windows -> "foo.dll"
  8. // MacOS -> "libfoo.dylib"
  9. // Linux -> "libfoo.so"
  10. dylib::library lib("./foo", dylib::decorations::os_default());
  11. // Custom OS decorations added
  12. // Windows -> "foo.dll"
  13. // MacOS -> "libfoo.so"
  14. // Linux -> "libfoo.so"
  15. auto custom_decorations = dylib::decorations(
  16. DYLIB_WIN_OTHER("", "lib"), DYLIB_WIN_OTHER(".dll", ".so")
  17. );
  18. dylib::library lib("./foo", custom_decorations);

Get a function or a variable

get_function
Get a function from the dynamic library currently loaded in the object

get_variable
Get a global variable from the dynamic library currently loaded in the object

C symbols

  1. // Load "foo" dynamic library
  2. dylib::library lib("./foo", dylib::decorations::os_default());
  3. // Get the C function "adder" (get_function<T> will return T*)
  4. auto adder = lib.get_function<double(double, double)>("adder");
  5. // Get the variable "pi_value" (get_variable<T> will return T&)
  6. double pi = lib.get_variable<double>("pi_value");
  7. // Use the function "adder" with "pi_value"
  8. double result = adder(pi, pi);

C++ symbols

  1. // Load "foo" dynamic library
  2. dylib::library lib("./foo", dylib::decorations::os_default());
  3. // Get the C++ functions "to_string" located in the namespace "tools"
  4. // The format for the function arguments is the following:
  5. // type [const] [volatile] [*|&|&&]
  6. auto int_to_string = lib.get_function<std::string(int)>("tools::to_string(int)");
  7. auto double_to_string = lib.get_function<std::string(double)>("tools::to_string(double)");
  8. // Get the variable "pi_value" located in the namespace "global::math"
  9. double pi = lib.get_variable<double>("global::math::pi_value");
  10. std::string meaning_of_life_str = int_to_string(42);
  11. std::string pi_str = double_to_string(pi);

Gather library symbols

You can collect the symbols of a dynamic library using the symbols method:

  1. // Load "foo" dynamic library
  2. dylib::library lib("./foo", dylib::decorations::os_default());
  3. // Iterate through symbols
  4. for (auto &symbol : lib.symbols()) {
  5. if (symbol.loadable)
  6. std::cout << symbol.demangled_name << std::endl;
  7. }

Miscellaneous tools

get_symbol
Get a C or C++ symbol from the dynamic library currently loaded in the object

native_handle
Returns the dynamic library handle

  1. dylib::library lib("./foo", dylib::decorations::os_default());
  2. dylib::native_handle_type handle = lib.native_handle();
  3. dylib::native_symbol_type symbol = lib.get_symbol("pi_value");
  4. assert(handle != nullptr && symbol != nullptr);
  5. assert(symbol == dlsym(handle, "pi_value"));

Exceptions

load_error
This exception is raised when the library failed to load or the library encountered symbol resolution issues

symbol_error
This exception is raised when the library failed to load a symbol

Those exceptions inherit from dylib::exception

  1. try {
  2. dylib::library lib("./foo", dylib::decorations::os_default());
  3. double pi_value = lib.get_variable<double>("pi_value");
  4. std::cout << pi_value << std::endl;
  5. } catch (const dylib::load_error &) {
  6. std::cerr << "failed to load 'foo' library" << std::endl;
  7. } catch (const dylib::symbol_error &) {
  8. std::cerr << "failed to get 'pi_value' symbol" << std::endl;
  9. }

Example

A full example about the usage of the dylib library is available HERE

Tests

To build unit tests, enter the following commands:

  1. cmake . -B build -DDYLIB_BUILD_TESTS=ON
  2. cmake --build build

To run unit tests, enter the following command inside build directory:

  1. ctest

Community

If you have any question about the usage of the library, do not hesitate to open a discussion

If you want to report a bug or provide a feature, do not hesitate to open an issue or submit a pull request