Libdlibxx
A generalized C++ wrapper around the POSIX dynamic libraries functions dlopen, dlsym, dlclose, etc.
Install / Use
/learn @m-renaud/LibdlibxxREADME
Libdlibxx
Libdlibxx is a generalized C++11 wrapper library around the dl
functions from <dlfcn.h> to handle the loading and symbol lookup in
dynamic libraries.
Dependencies
- Until
optionalis introduced into the standard, this code relies on Boost.Optional. - A C++11 compiler.
Licence
This library is licensed under the FreeBSD license.
Usage
Linking to libdlibxx
To link to this library, pass the command line argument -ldlibxx.
Loading Dynamic Libraries
// Construct a DL handle with a string.
dlibxx::handle lib("library-name.so");
// Given an already constructed DL handle, replace it with a new DL.
dlibxx::handle lib;
lib.load("library-name.so");
Library Loading Error Handling
If the library was loaded successfully, a call to the loaded()
function will return true. Error handling code could be performed as
follows after a library has been loaded.
if (!lib.loaded())
{
std::cerr << lib.error() << std::endl;
return 1;
}
Symbol Lookup
Symbol lookup is performed with the lookup member function. You must
pass in the type of the function as the template parameter and the name
of the function in the dynamic library as the function argument.
If the function was successfully loaded, then the optional when
cast to bool will return true, and false otherwise. After a
successful load, the function can be retrieved via a call to get().
// Get an optional<function<Signature>> to the function.
auto func_symbol = lib.lookup<void(int)>("function_name");
if (func_symbol)
{
std::function<void(int)> f = func_symbol.get();
f(5);
}
else
{
std::cout << "Symbol lookup failed.\n";
}
Class Instance Creation
Due to the frequency of which dynamic libraries are used to create an instance of an abstract class satisfying some interface, a simple interface for creating objects from factory methods is provided.
If the instance could not be created, a shared_ptr containing
nullptr will be returned.
struct base_type
{
virtual void foo() = 0;
};
std::shared_ptr<base_type> p = lib.create<base_type>("factory_function");
if (p)
p->foo();
else
std::cout << "Unable to create instance.\n";
Symbol Resolution Policy
When loading the dynamic library, it can be specified whether all symbols
should be bound on opening or only when they are referenced. The
default is to bind all symbols when the library is loaded (through the
use of dlibxx::resolve::now), but lazy binding is also available.
It can be specified in the constructor as follows:
dlibxx::handle lib("library-name.so", dlibxx::resolve::lazy);
Additionally, if you already have a handle, you can set the resolution policy for future library loads like so:
dlibxx::handle lib;
lib.resolve_policy(dlibxx::resolve::lazy);
Options
In addition to the open policy, the options available for the flag
argument to dlopen are also available. They can be set with the
set_options member function before opening the library by ORing the
enum values together. The values available are:
dlibxx::options::none = 0,
dlibxx::options::global = RTLD_GLOBAL,
dlibxx::options::local = RTLD_LOCAL,
dlibxx::options::no_delete = RTLD_NODELETE,
dlibxx::options::no_load = RTLD_NOLOAD,
dlibxx::options::deep_bind = RTLD_DEEPBIND
(See man dlopen for information on options.)
dlibxx::handle lib;
lib.set_options(dlibxx::options::global | dlibxx::options::no_load);
Example Code
Run make and change to the examples/ directory.
Run the demo code with ./demo and when prompted enter:
./liba.so./libb.so./libc.so
and observe the results.
Testing
To enable and run the unit tests you first need to ensure that you have initialized the submodules so that gtest/gmock are available:
git submodule update --init
Enable testing:
cd build
cmake -DDLIBXX_ENABLE_TESTS=ON ..
Running make will now build the unit tests as well. Run the tests with one of
the following:
make testctestctest -V- to see the output from gtest
Contributing
In order to successfully contribute code there must be corresponding test code that fully demonstrates that the contribution works as intended. See previous section on enabling and running the unit test suite.
Related Skills
node-connect
339.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.9kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
339.3kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.9kCommit, push, and open a PR
