In this post we will see how to create a (very) simple shared library in C.

A shared library is a set of compiled code that can be used by an application without embedding the whole library code inside the final application.

Shared libraries used in a "Hello World!" linux application

A simple C application on Linux uses some shared libraries provided by the os. Let's compile a hello world and check its dependencies to shared objects:

$ cat hello.c 
#include <stdio.h>

int main(void)
{
  printf("Hello world!\n");
  return 0;
}
$ gcc hello.c 
$ ./a.out 
Hello world!
$ ldd a.out 
        linux-vdso.so.1 =>  (0x00007fff14d78000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f095a16a000)
        /lib64/ld-linux-x86-64.so.2 (0x0000557334be6000)

We can see that our program already has 3 dependencies : linux-vdso.so.1, libc.so.6, ld-linux-x86-64.so.2.

The first is a shared libray that handles fast system calls, the second is the C standard library, and the third one is the dynamic linker/loader.

Create a shared library

We create a library with a single function in it:

$ cat lib_random.c
int getRandomNumber(void)
{
  return 4;
}
$ cat lib_random.h
int getRandomNumber(void);

We compile the source file lib_random.c with -shared and -fPIC:

$ gcc -shared -fPIC -o lib_random.so lib_random.c

The -shared option tells gcc to produce a shared object that can be linked to other objects.

The -fPIC option produces position-independent code suitable for dynamic linking (when the linking is not done at compile time, but at runtime).

Compile the application

We want to call the shared library lib_random.so from an application that will not embed the library in its binary.

$ cat random.c 
#include <stdio.h>
#include "lib_random.h"

int main(void)
{
  int x;
  x = getRandomNumber();
  printf("A random number is %d\n", x);
  return 0;
}

We compile the application against the shared library:

$ gcc -o random random.c -L. -l_random

The -L. options tells gcc to look in the current folder for libraries. The -l_random option tells gcc to look for libraries names lib_random.

We can check that the resulting binary does not contain the getRandomNumber function, since it will be dynamically linked during runtime:

$ objdump -S random | grep "^\S* <getRandomNumber>" | wc -l
0

Finally, when we try to run our home-made application, it fails:

$ ./random 
./random: error while loading shared libraries: lib_random.so: cannot open shared object file: No such file or directory

Oops, what did we do wrong?

$ ldd random
        linux-vdso.so.1 =>  (0x00007ffdabf90000)
        lib_random.so => not found
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f80708eb000)
        /lib64/ld-linux-x86-64.so.2 (0x0000563e30b2a000)

It seems that something is missing to tell random where to find the lib_random.so file.

The dynamic linker does not know where our lib resides, so we need to tell him where to look. This is done through LD_LIBRARY_PATH environment variable:

$ export LD_LIBRARY_PATH=$(pwd):$LD_LIBRARY_PATH
$ ./random 
A random number is 4

And finally it works! We built a small shared library that was dynamically linked and loaded at runtime.

Sources: this, this and that.


Configure multiple SSH keys for different Github accounts

dim. 27 août 2017 by Mick Cherry

This is my first article, so I wanted to start with an easy one :)

You can not add the same SSH key on two different github accounts. So, if you want to work with multiple github accounts on the same computer, you can follow this article!

Creation of SSH keys …

read more

Create a simple static library in C

jeu. 17 août 2017 by Mick Cherry

I only recently learned the difference between a static and a dynamic library in C, essentially because I have so far only worked with static libraries - and very few libraries.

This article will only cover a simple example of a static library in C.

The idea of a library (in …

read more