Loading of a C++ class from a shared library (Modern C++)

There is already a lot of stuff on internet, related to dynamic loading of classes from a shared library. However I couldn’t find a simple example and explanation on how to do it with the following conditions :

– Modern C++ (from c++11 to 17) : Use of smart pointers to store the classes from the libraries

– Cross-platform : Works on Linux & Windows.

– Generic enough to be used by a wide range of programs.

Introduction

One of the best ways to make your C++ program accept plugins is to use dynamic loading of a class from a library. According toWikipedia, dynamic loading is the process that allows you to retrieve functions and variables into the library. That’s very powerful, for multiple reasons :

– It requires no restart when you “load” or “unload” a shared library from an executable, because it isn’t statically linked.

– The library’s content is not included in the binary, and therefore the developer doesn’t have to compile it each time he wants to update the binary.

– The developer is able to push further the separation between non-related parts of his program, and to reuse them easier.

Imagine for example, programming an HTTP server. It must ideally have several modules, with different goals for each (SSL, PHP…). Instead of including all of them in one binary, why not make them shared libraries, and use them with dynamic loading ?

In this article, I’ll do my best to explain and show you a simple method to load classes from shared libraries, taking care of the conditions listed at the top.

What we’ll be building

A simple C++ program, running both on Linux and Windows. It will have a Core part (the executable), responsible for checking the libraries existence, and then to load, use and unload them. The libraries are classes that greet the user from the different Star Wars planets. They share a common interface, which is IPlanet, and is also known by the Core.

Here is a basic diagram to show how it works.

Note that my goal is to show a simple implementation of all of this, therefore adding error handling and/or some optimizations might be good once you get the concept.

Let’s get started !

The interface (API)

All the classes coming from the shared libraries will inherit from this interface. Having an interface is useful when you have multiple libraries, and the core won’t know every concrete class. The core is then able to manipulate each class through the interface.

– We use a conditional preprocessor macro : #ifdef to enter the condition only if we are compiling on a specific platform. Here it may be Windows (WIN32) or Linux (__linux__). We can’t use exactly the same code for both platforms because of the next point.

– Note that for Windows we have to include __declspec (dllexport) before the function prototype. More info on this here.

– There is this extern "C" line, wrapping some C-like functions. It is in this part that we will set our entry points to load and unload the library class right into and from our “core” program. To know why we need it, we must understand how dynamic loading works.

Note on dynamic loading process

To load something from a shared library, we need to know where to look at in the assembly file. That’s where symbols are useful. Symbols can be anything, like a function, or a variable, and, in our example, classes (remember Tatooine ?). As long as we know the name of the symbol we need, we can use a set of low-level functions : dlopen(), dlsym() and dlclose() for linux, LoadLibrary(), GetProcAdress() and FreeLibrary for Windows. These functions allow us to load the shared library into the memory, then to retrieve the symbol, to get the class from it and to unload the library.

All of this could work in C for example, where there is no (or little) “name mangling“. As said by Wikipedia, name mangling is the modification of variables names into the assembly file. It is required in languages implementing features like parametric polymorphism, templates, or namespaces. Like in C++ !

Indeed, if several functions share the same name but with a different signature, the compiler must clearly differenciate them in the final assembly. Mangling is made by the compiler.

By wrapping our “entry code” with extern "C", we ensure that no name mangling will be done by the compiler. The symbols in the assembly file will be exactly the same as the ones in our source code. Therefore we’ll be able to retrieve them easier. Simply by using their names !

So there are two entry points (symbols) for our class : allocator and deleter.

Allocator

We will get an instance of the library class through it. However we can’t return a smart pointer, because it isn’t valid C. We just return a C pointer, and we’ll transform it on the dlloader-side.

Deleter

This one will be called when we’ll need to destroy our class. It is important to have a destructor directly in the dynamic library, to ensure that the memory management will happen in it.

Well, that’s about it for the libraries ! I just included one library here, but the principle is the same for another library, as long as it obeys to the IPlanet interface.

The Dynamic Library Loader (DLLoader)

Hold on, this is quite a long tutorial, but it is worth it (I hope) ! Now is another interesting part : the dynamic library loader, which is included in your core.

First, let’s resume the process. Here are the steps we need to have it all working smoothly :

Note on the compilation

Alright, now remember that our code must run on Linux as well as on Windows. We will use the same concept of separated compilation, with OS macros, but in the CMakeLists this time.

Therefore we need two different source file, because the code to interact with shared libraries is very low level and OS-specific. One for Linux, and one for Windows. Here though, it won’t be .cpp files, but .h files. It will be easier to put everything in the header because the class is templated.

First, we need to create an interface for the DLLoader. Both Linux’s concrete DLLoader and Windows’ one will inherit from it.

We use the return of dlsym() to get each symbol we need.This variable is then casted to a function pointer, to make it exploitable.

So we have :– Allocator entry point : function pointer of type allocClass & held by the variable allocFunc.– Deleter entry point : function pointer of type deleteClass & held by the variable deleteFunc.

Finally, remember that we wanted to use smart pointers ? We shouldn’t use raw pointer anymore. That’s why we build it directly in this function, with the allocator and the deleter. Take a look at the overloads of std::shared_ptr’s constructor. Note that we call the deleter through a lambda, to pass it the raw pointer that we have to delete.

Windows’ DLLoader class

That’s basically the same principle. However the system calls are not the same, so don’t forget to change them. Here is the entire source code for this class.

In greet() and greetFromAPlanet() we use everything we just coded. As you see, we’re using shared pointers. Also, the core doesn’t know anything about either the Tatooine library, or the Bespin library. All it knows is the IPlanet interface.

That’s it, I hope you enjoyed learning this stuff as much as I did ! Don’t hesitate to send me remarks, or comments, I’ll be pleased to answer them.

Don’t forget to checkout the code hosted on Github for this tutorial as well, and may the force be with you.

Has Paris found its new main Tech event in VivaTechnology ?

It’s been 3 months since I went to the VivaTechnology event, but I was very busy these last weeks, and couldn’t find any time to write down my feelings about it…

VivaTechnology is an event that takes place in Paris, every year in June, since 2016. Its main goal is to bring together the players in the Tech ecosystem. It concerns big groups – Orange, Airbus, Google, Microsoft, IBM and many more – as well as startups, contractors, and investors. There’s even a day where the public is welcomed. An opportunity for everyone to discover the latest innovations in multiple fields : energy, luxury, food, transports…

Business…

The event was organized in a way that let people exchange very easily. My main goal, along with taking a pulse of the next tendencies in tech, was to find a part-time for the fall. It was very easy to talk with a lot of interesting people at stands, and I left with a lot of business cards, acquired in just a few hours. Special thanks to the mobile app developed for the event, and which was almost a social network on its own. It allowed the participants to “connect” while they met (and exchange later), and to be informed of the hours, location, topics of events.

These events were in majority talks, on interesting topics and with well-known speakers (Eric Schmidt for Alphabet, Bernard Arnault for LVMH, Daniel Zhang for Alibaba, …).

… And tech

Furthermore the event hosted a hackathon, with four challenges sponsored by big groups (Axa, Cisco, Microsoft and Sodexo). The participants had to build a team of speakers, developers and designers. Then they had to come with a solution for a given problem, all of this in less than 24 hours. I had the opportunity to win the 1st prize of the Microsoft’s challenge, with my team ! We prototyped a chatbot, called Angela, to improve the relations between co-workers, and unite them around their shared hobbies. It was my first experience of hackathons, and a great one ! We didn’t sleep, so it was very exhausting at the end, but we never gave up, and kept working as a team. I really hope to participate in other challenges like this one.

The Angela team, tired after 24 hours of work but very happy !

Anyway I really enjoyed the time spent at this event, and think my friends did too. Vivatechnology keeps getting bigger each year, and there was a lot more communication on it in 2017. It gathers a lot of different people, coming from different horizons, and having different goals. Bringing these people together is a great alternative to Las Vegas’s CES, or Barcelone’s MWC, which only focus on hardware/software.

So yeah, Paris has found its main tech event, in the way that it allows people to meet !

Theo

August 22, 2017

Elon Musk: Tesla, SpaceX, and the Quest for a Fantastic Future

Title:

Elon Musk: Tesla, SpaceX, and the Quest for a Fantastic Future

Author:

Ashley Vance

Genre:

Biography

Publisher:

Ecco

Release Date:

2015

"Elon came to the conclusion early in his career that life is short", Straubel said. "If you really embrace this, it leaves you with the obvious conclusion that you should be working as hard as you can."

You can love or hate the Elon Musk's personality, I can't imagine how it is possible not to have respect for him after having read this book. My biggest learning from this book is to never give up on your work when you're passionate about it, no matter what happens. Very inspiring.

That’s one of the many advises this book offers to those who want to improve their productivity as a developer, and a collaborator. It isn’t related to any programming language, that’s why everyone can read it. It helped me build better softwares in terms of maintainability, clarity, and also to improve my team-work. It describes simple and clear methods and architectures that you can use in your everyday projects. One of the most useful readings of this year.

Theo

A modern and lightweight Arch-Linux (xfce) configuration

What a better way to get in touch than to talk about our everyday configuration ? I’m currently working on an Arch Linux distribution. What I love about it is the huge amount of Sys Admin stuff I learned while installing it again and again, each time faster than before, and with a better knowledge of what I was doing. I’m not going to give you explanations on how to install it, but rather present you some packages I use to customize the default system. In my daily life I like to use XFCE.

System utilities

First, there’s a few packages not available through pacman or yaourt (the Arch Linux package managers). You’ll have to manually install them (by that I mean going to their website, and downloading them directly) :

yaourt redshift oh-my-zsh

redshift allows you to change the temperature of your screen. It tires the eyes less than having a blue screen, especially during the night.

oh-my-zsh is a zsh plugin that easily lets you configure your zsh.

Then, with pacman (sudo pacman -S [packages]):

lxrandr xfce4-screenshooter xscreensaver

lxrandr is a small utility that lets you configure multiple screens. It is graphical, and very user-friendly.

The screenshooter is the official xfce – well, get ready – screenshooter. A cool shortcut to launch it at any time is [Windows] + [Screen] (in Settings > Keyboard > Application Shortcuts).

I like to use xscreensaver to lock my PC. It’s customizable and there are plenty themes available. I often even display a RSS flux. It starts with the xscreensaver-command --lock command. It can be configured through xscreensaver-command --demo.

Xfce is faaaast.

I didn’t have the opportunity to test in depth a lot of graphical interfaces. Yet, it’s because xfce remains my favorite, and I don’t feel like testing other GUI, as this one entirely supplies my needs. It’s very fast, and highly customizable. During summer, I ended up having this ChromeOS like desktop, on xfce. Now I went back to more classical stuff :

Autostart xfce at login

Simply add this line to your zshrc config file, if this is the shell you’re using :

startxfce4

I’m not found of login managers, as they tend to slow down the boot time. Xfce is my only graphical interface, so I neither need to switch between it and something else, nor to change the language, keyboard disposition or brightness each time I log in. That’s why a simple console login is entirely sufficient for me.

A beautiful xfce interface

Here’s a beautiful theme, for afficionados of flat and sober themes like me. Its creator also made a great theme for firefox/chrome. The rendering is beautiful, and without any noticed bug so far.

It has several levels of configuration, from light to dark, all very well explained on the github page. It works well with this icon theme, and this cursor theme.

What you need to do if you want your main folders to always have a logo on them when displayed in thunar (the default GUI file viewer), is to add these lines to a file called ~/.config/user-dirs.dirs :

This looks like a completely different xfce now, doesn’t it ? Of course, don’t forget to customize the panels to fulfill your needs. I personally like to have a few launchers in a Windows-like style. The softwares icons you’ll need can be downloaded on Google and then added to the /usr/share/icons folder.

Conky

Conky is a little tool that allows you to display system informations directly on your desktop. You can set the refreshing rate, and choose between a lot of informations to display (list of available variables). I like to keep it simple, and to only display time and date. Here’s what my ~/.conkyrc file looks like :

There are plenty ways to configure the date and time format, listed here.

That’s it for my Arch configuration. I mainly talked about the graphical customization, because I like to interact with my OS through the GUI as well as through the command line. When the system is freshly installed, you already have almost every console tool you need, but, unlike Windows (already good-looking when installed), if you want your GUI (xfce) to look modern, you have to accept to take some time to customize it. Yes, I think xfce is a great GUI as it is fast and customizable, but, by default, it’s also very old-fashioned !