The goal of this C++ library is to load dynamic libraries (.so, .dll, .dylib) and access its functions and global variables at runtime.
⭐ Don't forget to put a star if you like the project!
Works on Linux
, Windows
, MacOS
You can fetch dylib
to your project using CMake
:
include(FetchContent)
FetchContent_Declare(
dylib
GIT_REPOSITORY "https://github.com/martin-olivier/dylib"
GIT_TAG "v1.8.3"
)
FetchContent_MakeAvailable(dylib)
You can also click HERE to download the dylib
header file.
The dylib
class can load a dynamic library at runtime:
dylib lib("./dynamic_lib.so");
The dylib
class can detect the file extension of the actual os using dylib::extension
:
dylib lib("./dynamic_lib", dylib::extension);
or
dylib lib;
lib.open("./dynamic_lib", dylib::extension);
open
Load a dynamic library into the object. If a dynamic library was already opened, it will be unloaded and replaced
close
Unload the dynamic library currently loaded in the object. This function will be automatically called by the class destructor
// Load ./dynamic_lib.so
dylib lib("./dynamic_lib.so");
// Unload ./dynamic_lib.so and load ./other_dynamic_lib.so
lib.open("./other_dynamic_lib.so");
// Unload ./other_dynamic_lib.so
lib.close();
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
// Load ./dynamic_lib.so
dylib lib("./dynamic_lib.so");
// Get the function adder (get_function<T> will return std::function<T>)
auto adder = lib.get_function<double(double, double)>("adder");
// Get the global variable pi_value
const double &pi = lib.get_variable<double>("pi_value");
// Use the function adder with pi_value
double result = adder(pi, pi);
operator bool
Returns true if a dynamic library is currently loaded in the object, false otherwise
has_symbol
Returns true if the symbol passed as parameter exists in the dynamic library, false otherwise
native_handle
Returns the dynamic library handle
void example(dylib &lib)
{
if (lib)
std::cout << "Something is currently loaded in the dylib object" << std::endl;
if (lib.has_symbol("GetModule"))
std::cout << "GetModule symbol has been found" << std::endl;
dylib::native_handle_type handle = lib.native_handle();
}
handle_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.
This usually happens when you forgot to put DYLIB_API
before a library function or variable
Those exceptions inherit from dylib::exception
try {
dylib lib("./dynamic_lib.so");
const double &pi_value = lib.get_variable<double>("pi_value");
std::cout << pi_value << std::endl;
}
catch (const dylib::exception &e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
A full example about the usage of the dylib
library is available HERE
If you use CMake to build a dynamic library, running the below CMake rule will allow you to remove the prefix
lib
for macOS and linux, ensuring that the library shares the same name on all the different OS:
set_target_properties(target PROPERTIES PREFIX "")
Without CMake rule | With CMake rule | |
---|---|---|
Linux | libmalloc.so | malloc.so |
MacOS | libmalloc.dylib | malloc.dylib |
Windows | malloc.dll | malloc.dll |
To build the unit tests, enter the following commands:
cmake . -B build -DBUILD_TESTS=ON
cmake --build build
To run the unit tests, enter the following command:
# on unix
./unit_tests
# on windows, in "Debug" folder
./unit_tests.exe