C/C++ program compilation and linking (3) The concept of dynamic library


The fundamental goal of dynamic libraries is the same as that of static libraries, to achieve code reuse. But their methods are fundamentally different.
The static library is directly linked into the program during program generation, and all required symbols are included in the executable program, so the static executable program will become larger when the executable program is linked, and no additional libraries are needed when the executable program is running.
The stage of dynamic library reuse is during the execution program loading period. The dynamic library is separated from the execution program, so the dynamic library does not affect the size of the execution program, and the dynamic library can be updated without affecting the client program (as long as the symbol remains unchanged). When the executable program is loaded into the memory, the loader resolves the symbol of the executable program to the correct address, which is the address mapped to the process memory map by the dynamic library.

dynamic link

Build a dynamic library

Compared with the construction of static libraries, the process of building dynamic libraries is a complete construction process, including compilation and linking.
The binary file generated by building the dynamic library is essentially the same as the executable file, the only difference is that the dynamic library lacks a startup program routine for independent execution.

Generate dynamic library 1.png

libc (C runtime library) in Linux can be run directly. In Linux, we can modify the dynamic library so that it can run independently.

link to client program

When linking a dynamic library, the linker doesn't do any checking of the binary interface (symbols) of the dynamic library, it doesn't look up sections or section sizes, and it doesn't splice sections into the final binary.
The linker will only check that the symbols needed in the binary are all found in the dynamic library. Once all the symbols are found, the linker does its job and creates the executable. The so-called just thinks that "all symbols can be parsed correctly".

Runtime loading and symbol resolution

The operations performed during program loading are very important, because at this stage it will be verified whether the dynamic library linked by the linker can work properly.
The symbols required by the executable in the copy of the dynamic library binary have been verified during a previous build.
Now the following operations need to be done at runtime:

  1. The executable program must first find the location of the dynamic library binary file. Every operating system has a set of rules that dictate where the loader should look for binaries for dynamic libraries.

  2. The process needs to load the dynamic library into the memory map. At this time, it must ensure that the promises in the link during the construction phase can be fully satisfied at runtime . In fact, loading a dynamic library at runtime must contain the symbols required by the "same" build phase. More precisely, "same" for a function symbol means that the function symbol in the runtime dynamic library must be identical to the full function signature (dependencies, function name, argument list, and linking and calling convention) in the build phase.

  3. At runtime, the symbol of the executable program needs to be correctly resolved to the correct address, which is the address mapped by the dynamic library to the process memory map.

Dynamic library usage

The dynamic library is the cornerstone of the operating system. In the operating system, many functional modules are organized into a dynamic library. When the program is running, it is loaded into the program memory space by the loader as needed.
But the use of dynamic libraries is more troublesome than static libraries, including two basic points:

  • The location of the dynamic library

For some core dynamic libraries (such as libc.so, libstd++.so, etc.), these are not problems, because the locations of these libraries have been pre-built into the system. The loader will give priority to these fixed paths to find.
But for our own programs that rely on dynamic libraries, there must be two points in order to run: 1. There are dynamic libraries required by the program in the operating system. 2. Specify the path where the dynamic library is located for the loader.
Of course, there are rules for the loader to find the path of the dynamic library.

  • The version of the dynamic library

The difference of version corresponds to the difference of symbols for the client program.
Like the path, for the functional dynamic library of the operating system itself, the version is the most suitable version adapted to the operating system.
The version naming of the dynamic library also has rules, and the loader loads the corresponding version of the dynamic library according to this rule. Understanding this rule is critical if there are multiple versions of the library within the operating system.

Guess you like

Origin blog.csdn.net/mo4776/article/details/129354093