1. 程式人生 > >A Trip to the Library: Static vs. Dynamic Libraries and Why They’re Awesome

A Trip to the Library: Static vs. Dynamic Libraries and Why They’re Awesome

A Trip to the Library: Static vs. Dynamic Libraries and Why They’re Awesome

In programming, a library is a collection of object code that can be used as a single entity during the linking phase of compilation when creating an executable program. If you are unfamiliar with the 4 stages of compilation, you should first read

this article first. In C/C++, there are two types of libraries, Dynamic and Static. This article will focus on Dynamic Libraries, but if you want to know more about Static Libraries, check out this article I previously wrote.

Why use Libraries?

Libraries offer multiple benefits such as code reusability. This also adds to greater ease during the software development process because one need not specify every single file during the linking process. One can simply refer to the library as a single entity, simplifying the compilation process. Libraries also boost code reusability and support sharing code between programs and applications.

The way that dynamic libraries and static libraries differ most is how they relate to the executable. Static libraries are statically linked to the executable during the linking phase of compilation. This means the actual machine code of the subroutines inside of the main function is included in the final executable file. In contrast, dynamic libraries are not included in the executable, but are tied to the executive. The process of dynamic linking happens at runtime and the dynamic library is loaded when the program starts.

One of the main benefits of dynamic linking is size as a program grows. Imagine if a program were statically linked. As this program grows and calls more and more functions inside of its source code, the final executive file consequently grows proportionately to the number of functions added. This is due to the fact, as previously mentioned, that statically linked files contain the actual object code of its library subroutines. In contrast, dynamic linking offers the benefit of reduced disk size because only the memory address of where the function is loaded is included in the executable.

This also brings up the issue of recompiling. Because actual machine code is statically linked into the executable, if one decided to modify the code of a library function, one must recompile the entire program. This may slow down the development process. In contrast, Dynamic linking offers greater flexibility in terms of editing code. Because the address of the function in memory is included in the executable, the executable reflects changes in the function’s code without having to recompile the entire program.

That being said, dynamic linking can be fragile because if the name of the library changes, that would affect the executable file and render the link broken.

How to create a Dynamically Linked Library

To create a Dynamic Library on a Linux OS, we first have to create object code files from our source code. To do this, we will run the following command in the terminal.

gcc -fPIC -Wall -c *.c

This command will run the GCC compiler on all files that end with a .c extension (i.e. all C files). The -c flag tells the compiler to stop before linking so that the compiler outputs object files of the respective .c files. The -fPIC flag is key and specifies that the object code should be position independent in memory, a characteristic of code in dynamic libraries.

Next, we want to combine the position independent object files into a single identity — the dynamic library. To do that, we run the command

gcc -shared *.o -o libYAY.so

This creates a dynamic library, also called “shared object” (hence the .so extension) from all of the object files in our current directory. According to man gcc, the -shared flag “produce[s] a shared object which can then be linked with other objects to form an executable.” The -o flag allows the user to specify an output name, and in this case, our library is called libYAY.so.

YAY!! :D

Using our Library

To compile with a library, we must use the -l flag, followed by the name of the library without the lib prefix and the .so extension. The -L flag tells the linker where to look for the library in addition to the standard locations of where libraries are kept. In this case, our shared library file is in our current directory (denoted by .) .

gcc my_program.c -L. -lYAY -o my_program

When we reach the linking stage of compilation, the linker first checks the LD_LIBRARY_PATH environment variable, a colon separated list of directories that should be checked first for shared object files. Otherwise, it checks the system’s default search path such as /usr/lib or /usr/local/lib.

Well, there you go! Now go on and prosper with your newfound knowledge!