The goal of this C++ Library is to load dynamic libraries (.so, .dll, .dylib) and access its functions and global variables at runtime.
Works on Linux
, Windows
, MacOS
Click HERE to download the dylib header file
⭐ Don't forget to put a star if you like the project!
The dylib class can load a dynamic library at runtime:
dylib lib("./myDynLib.so");
The dylib class can detect the file extension of the actual os using dylib::extension
:
dylib lib("./myDynLib", dylib::extension);
or
dylib lib;
lib.open("./myDynLib", dylib::extension);
open
Load a dynamic library into the object. If a dynamic library was already opened, it will be unloaded and replaced
close
Close the dynamic library currently loaded in the object. This function will be automatically called by the class destructor
// Load ./myDynLib.so
dylib lib("./myDynLib.so");
// Unload ./myDynLib.so and load ./otherLib.so
lib.open("./otherLib.so");
// Close ./otherLib.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 ./myDynLib.so
dylib lib("./myDynLib.so");
// Get the global function adder
auto adder = lib.get_function<double(double, double)>("adder");
// Get the global variable pi_value
double pi = lib.get_variable<double>("pi_value");
// Use the function adder with pi_value
double result = adder(pi, pi);
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("./myDynLib.so");
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;
Let's write some functions in our forthcoming dynamic library:
// myDynLib.cpp
#include <iostream>
#include "dylib.hpp"
DYLIB_API double pi_value = 3.14159;
DYLIB_API void *ptr = (void *)1;
DYLIB_API double adder(double a, double b)
{
return a + b;
}
DYLIB_API void print_hello()
{
std::cout << "Hello!" << std::endl;
}
Let's build our code into a dynamic library:
g++ -std=c++11 -fPIC -shared myDynLib.cpp -o myDynLib.so
Let's try to access the functions and global variables of our dynamic library at runtime with this code:
// main.cpp
#include <iostream>
#include "dylib.hpp"
int main()
{
try {
dylib lib("./myDynLib.so");
auto adder = lib.get_function<double(double, double)>("adder");
std::cout << adder(5, 10) << std::endl;
auto printer = lib.get_function<void()>("print_hello");
printer();
double pi_value = lib.get_variable<double>("pi_value");
std::cout << pi_value << std::endl;
auto &ptr = lib.get_variable<void *>("ptr");
if (ptr == (void *)1)
std::cout << "1" << std::endl;
}
catch (const dylib::exception &e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Let's build and run our code:
g++ -std=c++11 main.cpp -o out -ldl
./out
Output:
15
Hello!
3.14159
1
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 |