Skip to content

LaFeuilleMorte/DyLib

 
 

Repository files navigation

DyLib - Dynamic Library Loader for C++

DyLib MIT license CPP Version

GitHub watchers GitHub forks GitHub stars

workflow codecov

GitHub download

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

Compatibility

Works on Linux, Windows, MacOS

Installation

Click HERE to download the DyLib header file
Don't forget to put a star on the project 🌟

Documentation

DyLib Class

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 and Close

open
Load a dynamic library into the object. If a dynamic library was already opened, it will be unload 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 a Function or a Variable

getFunction
Get a function from the dynamic library currently loaded in the object.

getVariable
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.getFunction<double(double, double)>("adder");

// Get the global variable pi_value

double pi = lib.getVariable<double>("pi_value");

// Use the function adder with pi_value

double result = adder(pi, pi);

DyLib Exceptions

handle_error
This exception is thrown when the library failed to load or the library encountered symbol resolution issues

symbol_error
This exception is thrown when the library failed to load a symbol. This usualy happens when you forgot to mark a library function or variable as extern "C"

Those exceptions inherits from DyLib::exception

try {
    DyLib lib("./myDynLib.so");
    double pi_value = lib.getVariable<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;

Exemple

Lets write some functions in our future dynamic library :

// myDynLib.cpp

#include <iostream>

extern "C" {
    double pi_value = 3.14159;
    void *ptr = (void *)1;

    double adder(double a, double b)
    {
        return a + b;
    }

    void printHello()
    {
        std::cout << "Hello!" << std::endl;
    }
}

Lets build our code into a dynamic library :

g++ -std=c++11 -fPIC -shared myDynLib.cpp -o myDynLib.so

Lets 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.getFunction<double(double, double)>("adder");
        std::cout << adder(5, 10) << std::endl;

        auto printer = lib.getFunction<void()>("printHello");
        printer();

        double pi_value = lib.getVariable<double>("pi_value");
        std::cout << pi_value << std::endl;

        auto &ptr = lib.getVariable<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;
}

Lets build and run our code :
g++ -std=c++11 main.cpp -o out -ldl
./out

Output :

15
Hello!
3.14159
1

About

Cross-platform Dynamic Library Loader for C++

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C++ 73.7%
  • CMake 26.3%