Code Monkey home page Code Monkey logo

dynamic-loading-example's Introduction

Dynamic Loading Example

I've recently become interested in how dynamic loading of shared objects works in c++ and other languages. Dynamic loading has found it's main use as a basis for plugin systems for applications like notepad++ for example, which loads plugins from dll files in a certain directory in it's folder structure.

How does it work?

Dynamic library loading works similarly to how linking against a shared library does (at least to my knowledge of these concepts). A library must first be loaded from the file system, and then you can search for certain symbols within this library that correspond to functions, or variables, etc.

Examples

Here's a small example in c++:

An example library that we can import functions from at runtime:

// file: greetings.cpp

#include <iostream>

extern "C" {
    void say_hello() {
        std::cout << "Hello world?\n";
    }
    
    void say_good_evening() {
        std::cout << "konbanwa!\n";
    }
}

The main point to take from the code above is the extern "C" wrapping the functions that we want to expose. This is because the tools that we're going to use later on require the C naming conventions, and since c++ does some interesting things with it's name mangling, we're required to export these functions using the C naming convention.

A side effect of this is that we can't have overloaded functions in our extern block, since the exported symbol names would be the same and would therefore clash.

Next up we have the program that will load this shared object at runtime:

// file: main.cpp

#include <dlfcn.h>
#include <iostream>

// A function pointer
using Func = void*(*)(void);

int main(void) {
    void* handle = dlopen("libgreetings.so", RTLD_LAZY);
    if(!handle) {
        std::cerr << dlerror() << std::endl;
        return 1;
    }
    
    void* func = (Func)dlsym(handle, "say_hello");
    func();
    
    return 0;
}

There's a few things going on here, so let's explain:

#include <dlfcn.h>

The dlfcn.h header defines all of the functions required to interact with dynamically loaded functions. This is where the dlopen, dlerror, and dlsym functions seen later on in the example come from.

void* handle = dlopen("libgreetings.so", RTLD_LAZY)

dlopen opens a shared object file, which in this case is libname.so. The RTLD_LAZY macro defines how eager we are to load the symbols in the object. In this case we're going to load them lazily, i.e, only when we need them. Notice that dlopen returns a void*, in this case, this just means that handle is a pointer into the shared object. This handle is what we're going to use to interact with the symbols in this library.

using Func = void*(*)(void);

...

Func func = (Func)dlsym(handle, "say_hello");
func();

Here we see another useful function from the dlfcn.h header, dlsym. This function allows us to acquire a pointer to a symbol inside of the shared object. In our case, we're trying to grab a function named say_hello. However, because this function returns a void*, we can't actually call it like a function. Thus the function pointer (Func) using declaration above. This allows us to cast the returned pointer to a callable function type, which we use on the next line.

And then a makefile to round it all out:

# file: Makefile

all: main libgreetings.so

main: main.cpp
    g++ main.cpp -o main
    
libgreetings.so: greetings.cpp
    # -fpic Position Independent Code -> for the compilation step
    # -shared Create a shared object -> for the linking step
    g++ -fpic -shared greetings.cpp -o libgreetings.so

The rest of this repository includes an example of a dynamic loading based plugin system. It includes a few interesting tricks such as GCCs __attribute__((constructor)) attribute and an inheritance based plugin architecture (if you can call it that lol).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.