Dynamic Libraries in C

Dynamic Libraries in C

This post is part of a set of articles exploring different edges of the intricacies of computer science. In this one, I will explain what libraries are and how to create and use dynamic libraries in the C programming language.

Why using libraries in general and how do they work:

One of the challenges in software development is while the program is developed, code and files, tend to grow larger and larger, bringing more challenges for their developers and especially maintainers and increasing the compilation and linking time. 

A way to address these problems is the implementation of libraries. A library is a collection of pre-compiled routines used in programs. Libraries are called and used in the source code without being defined within it, and the compiler adds them during the compilation process.

A static library is a collection of object files that code is "copied" into the source code at the compilation moment. At the same time, a dynamic or shared library is a collection of functions compiled and stored in an executable to be linked by other programs at running time.

  • Using libraries allows us to save development time, avoiding to write basic everyday routines.
  • Its functions are portable, meaning that they could be implemented in any computer that runs the program developed.

How to create a static library: [Linux systems]

1. First, we need to create the object file ( .o) from the source code ( .c) of each function we want to include in the library. Compile every .c file with -c flag to obtain each object file. In terminal enter the following command:

gcc -c name_of_file.c

For a bunch of files in the current directory, you can type 

gcc -c *.c

2. Once we have object file(s), we can now bundle them into one static library using the archiver program [ar]. In the next example, the “c” flag creates the library if it doesn’t already exist, and the “r” option replaces older object files with the new ones we add to the library. 

ar -rc name_of_libary.a name_of_file_1.o name_of_file_2.o


3. After an archive is created or modified; there is a need to index it. This index is later used by the compiler to speed up symbol-lookup inside the library. The command used to create or update the index is called 'ranlib' and is invoked as follows: 

randlib name_of_library.a

How to use them:

Now that the library is created, we can use it for a program; they should include a prototype for each of the functions that exist in your library. If you’re using a header file for these prototypes, make sure to include the name of that file in your other files by using #include “<header file>”

gcc main.c -L. -lname_of_library -o myprog

When compiling program files, we have to tell the compiler to use the library files and where to find them. 

Flags used:

>> ‘-L.’ tells the compiler it can find the library file in the current directory.

>> And -l says “link with this library file followed the name. It’s important to leave the ‘lib’ and ‘.a’ out of the flag because the compiler already identifies library files that way. 

>> ' -o ' the output name of the executable file of our program.

In conclusion, the main advantage of using static libraries is the speed of the app, due to all function are embed in the code, no pull request or searches in the system will be needed.

In addition, all dependencies are no longer an issue, because all libraries are present in the code and in the latest version.

How to create a dynamic library with GNU:

To start, we need to create the object files first with the command: 

gcc -fPIC -c *.c

This command generates one object file .o for each source file .c . The -fPIC flag ensures that the code is position-independent. It means it wouldn’t matter where the computer loads the code into memory. The next step is to enter this command:

gcc *.o -shared -o lib_name.so

The command creates a lib_name.so file with all .o files, and the -shared flag tells the compiler to produce a shared object, which can then be linked with other objects to form an executable. 

How to use them :

To use a dynamic library is needed to export the LD_LIBRARY_PATH environment variable, which has a value of the first directories who are going to search for libraries included in the executable file:

$ export LD_LIBRARY_PATH=$PWD/lib_name.so:

Alternatively, to configure dynamic linker run-time bindings, we can use the ldconfig command with the -n and -L flags.

And last but not least: to compile the program to an executable file, we have to enter the following :

gcc main.c -L. -l_name -o exec_program

Where -L flag specifies the path to the library, in our case, it is the current directory, and -l flag specifies the name of the library to use. Please note: the lib prefix and the .so extension are committed. A finally, the -o flag is used to name the output file.

To find out what functions a library has, we should use the nm command:

nm lib_name.so

To print the dependencies of a library, use the ldd command:

ldd lib_name.so

Differences between static and dynamic libraries:

There are some differences between static and dynamic libraries. Some are illustrated in the following illustration:

No hay texto alternativo para esta imagen

Hope you find this post useful and please feel free to comment, ask, or if you find anything incorrect, let me know.


To view or add a comment, sign in

More articles by Martin M. Saavedra

Others also viewed

Explore content categories