1. Library files
The so-called library file, readers can be equivalent to a compressed package file, the file usually contains more than one object file (that is, binary file).
It is worth mentioning that the code stored in each object file in the library file is not a complete program, but a practical functional module. For example, a C
language library provides a number of functions (such as scanf()
, printf()
, strlen()
etc.), C++
library functions provide not only have to use, there are a large number of pre-designed classes (such as string
String class).
The generation of the library file greatly improves the programmer's development efficiency, because many functions do not need to be developed from 0 at all, just call the library file containing the function directly. Also, call the library method is also very simple to C
language printf()
output function, for example, the program just introduced <stdio.h>
the header file, you can call the printf()
function.
Why is the header file involved when calling the library file? First of all, header files and library files are not the same thing. The biggest difference between them is:
- The header file only stores the declaration part of these functional modules such as variables, functions or classes;
- The library file is responsible for storing the specific implementation parts of each module;
Readers can understand this way: all library files are provided with corresponding header files as the interface to call it. In other words, library files cannot be used directly, and can only be called indirectly through header files.
The biggest advantage of the combined access mechanism of header files and library files is that sometimes we only want others to use the functions we have implemented, and do not want to disclose the source code of the functions. We can make them as library files so that users can obtain It is a binary file, and the header file only contains the declaration part, so that the purpose of "hiding the source code" is realized without affecting the user's use.
In fact, library files are just a general term, referring to a type of compressed package, they all contain functional and practical object files. You should know that although the library file is used in the linking phase of the program, the compiler provides two ways to achieve linking, which are called static linking and dynamic linking.
- The library files that use static linking to achieve linking operations are called static link libraries;
- A library file that uses dynamic linking to achieve linking operations is called a dynamic link library;
In C
, C++
the actual development process, in addition to using the system library files, we can create a static link library or DLL according to actual needs, manually.
2. Static Link Library
The static link library realizes the link operation in a very simple way, that is, where the function module in the library file is used in the program file, the GCC
compiler will directly copy the template code to the appropriate location of the program file, and finally generate an executable file.
Using static library files to implement program linking operations has both advantages and disadvantages:
- The advantage is that the generated executable file can run independently without the support of any static library file (strong portability);
- The disadvantage is that if the same function module in the library is called multiple times in the program file, the module code will inevitably be copied multiple times, and the generated executable file will contain multiple pieces of identical code, causing code redundancy.
Compared with the executable file generated by the dynamic link library, the executable file generated by the static link library has a larger volume.
- In the
Linux
release version of the system, the extension of static link library files usually.a
represent; - In the
Windows
system, the suffix static link library file name.lib
;
2.1 Create a static link library
A static link library is actually equivalent to a compressed package, which can contain multiple source files. But it should be noted that not any source file can be processed into a static link library, it needs to meet at least the following two conditions:
- Source files only provides the code can be reused, such as functions, etc. designed, can not contain
main
the main function; - While the source file realizes the module function, it also provides an interface to access it, that is, the header file that contains the declaration part of each function module;
Sample code structure:
wohu@ubuntu:~/cpp/src$ tree
.
├── function.h
├── greeting.cpp
├── main.cpp
└── name.cpp
0 directories, 4 files
wohu@ubuntu:~/cpp/src$
function.h
Code
void sayGreetings();
void sayName();
greeting.cpp
The code, which contains it #include "function.h"
, does not need to include the header file when the static library is not created.
#include <iostream>
#include "function.h"
void sayGreetings()
{
std::cout << "hello,world" << std::endl;
}
name.cpp
The code, which is included #include "function.h"
, does not need to include the header file when the static library is not created.
#include <iostream>
#include "function.h"
void sayName()
{
std::cout << "My name is wohu" << std::endl;
}
main.cpp
Code
#include <iostream>
#include "function.h"
int main()
{
sayGreetings();
sayName();
return 0;
}
For name.cpp
and greeting.cpp
are in line with the above two conditions, it can be processed into a static link library. And according to actual needs, we can compress them collectively into a static link library, or each can be compressed into a static link library.
The process of packaging the source file as a static link library is very simple, just go through the following 2 steps:
- Compile all specified source files into corresponding target files
wohu@ubuntu:~/cpp/src$ g++ -c greeting.cpp name.cpp
wohu@ubuntu:~/cpp/src$ ls
function.h greeting.cpp greeting.o main.cpp name.cpp name.o
wohu@ubuntu:~/cpp/src$
- Then using
ar
compressed instructions, the generated object files into a static link library, the basic format is as follows:
ar rcs 静态链接库名称 目标文件1 目标文件2 ...
About ar
compression packing instructions, as well as rcs
the meaning and function of each option, please refer to the Linux ar command
The important point is that the static link library cannot be named arbitrarily, and the following naming rules must be followed:
libxxx.a
Linux
Under the system, the suffix of the static link library is.a
;Windows
Under the system, the suffix of the static link library is.lib
;
Among them, xxx
on behalf of that we played for the library name, such as Linux
the system comes with some static link library name libc.a
, , libgcc.a
, libm.a
their names are c
, gcc
and m
.
Next, pack greeting.o
and name.o
package into a static link library:
wohu@ubuntu:~/cpp/src$ ar rcs libmyfunction.a name.o greeting.o
wohu@ubuntu:~/cpp/src$ ls
function.h greeting.cpp greeting.o libmyfunction.a main.cpp name.cpp name.o
wohu@ubuntu:~/cpp/src$
Among them, libmyfunction.a
that is name.o
, greeting.o
packaged together generated static link library, myfunction
a library name our custom.
2.2 Use static link library
The use of the static link library is very simple, that is, in the linking stage of the program, the static link library and other object files are linked together to generate an executable file.
Using the previous code as an example, we will first main.cpp
file is compiled into object files:
wohu@ubuntu:~/cpp/src$ g++ -c main.cpp
wohu@ubuntu:~/cpp/src$ ls
function.h greeting.cpp greeting.o libmyfunction.a main.cpp main.o name.cpp name.o
wohu@ubuntu:~/cpp/src$
On this basis, we can directly execute the following commands to complete the link operation:
wohu@ubuntu:~/cpp/src$ g++ -static main.o libmyfunction.a
wohu@ubuntu:~/cpp/src$ ls
a.out function.h greeting.cpp greeting.o libmyfunction.a main.cpp main.o name.cpp name.o
wohu@ubuntu:~/cpp/src$
Among them, -static
the option to force GCC
the compiler to use a static link library.
Note that if GCC
the compiler can not find the tips libmyfunction.a
, you can also use the following link operation is accomplished:
wohu@ubuntu:~/cpp/src$ g++ -static main.o -L /home/wohu/cpp/src -lmyfunction
wohu@ubuntu:~/cpp/src$ ls
a.out function.h greeting.cpp greeting.o libmyfunction.a main.cpp main.o name.cpp name.o
among them,
-L
(UppercaseL
) option is used toGCC
specify the storage location of the static compiler link library (can use pwd command to view specific storage location);-l
(LowercaseL
) option is used to indicate the name of the required static link library, pay attention to names used herein refers to thexxx
part, and will recommend-l
andxxx
direct conjunction (ie-lxxx
), without intermediate spaces.
As a result, it generates a.out
an executable file:
wohu@ubuntu:~/cpp/src$ ./a.out
hello,world
My name is wohu
wohu@ubuntu:~/cpp/src$
3. Dynamic Link Library
Dynamic link library, also known as shared link library. Different from static link library, when the dynamic link library is used to realize the link operation, where the function module of the library file is needed in the program file, the GCC
compiler will not directly copy the code of the function module to the file, but will copy the location information of the function module Record to the file, and directly generate the executable file.
Obviously, the executable file generated in this way cannot run independently. When the executable file generated by the dynamic link library is run, the GCC
compiler will load the corresponding dynamic link library into the memory together. Since the position information of the required function module is recorded in the executable file in advance, the existing dynamic link library It can also run successfully with the support of.
The advantages and disadvantages of using the dynamic link library to realize the connection operation of the program are just the opposite of the static link library:
- The advantage is that because the executable file records the address of the function module, the real implementation code will be loaded into the memory when the program is running, which means that even if the function module is called multiple times, the same implementation code is used (This is also the reason why the dynamic link library is called a shared link library).
- The disadvantage is that the executable file generated by this method cannot be run independently, and the corresponding library file must be used (poor portability).
Compared with the executable file generated by the static link library, the executable file generated by the dynamic link library has a smaller volume, because a bunch of redundant codes will not be copied inside.
- In the
Linux
release version of the system, the extension dynamic link library is usually.so
represented; - In the
Windows
system, the suffix dynamic link library named.dll
;
GCC
When the compiler generates an executable file, it will give priority to the use of the dynamic link library to achieve the link operation by default. Unless there is no dynamic link library required by the program file in the current system environment, the GCC
compiler will select the corresponding static link library. If both are not (or GCC
compiler not found), the link fails.
3.1 Create a dynamic link library
In general, there are two ways to create a dynamic link library.
- Directly create dynamic link library source files, using the
gcc
basic format of the command is implemented as follows:
gcc -fpic -shared 源文件名... -o 动态链接库名
among them,
-shared
Option is used to generate dynamic link library;-fpic
(Also written as-fPIC
function) option is to makeGCC
the compiler generate dynamic link library (archive multiple object files), indicates the address of each object file functions, classes, and other functional modules use a relative address, rather than absolute address. In this way, no matter where the link library is loaded into the memory in the future, it can be used normally.
For example, the front of the project greeting.cpp
, name.cpp
these two source files to generate a dynamic link library, execute the command as follows:
wohu@ubuntu:~/cpp/src$ g++ -fPIC -shared name.cpp greeting.cpp -o libmyfunction.so
wohu@ubuntu:~/cpp/src$ ls
function.h greeting.cpp libmyfunction.a libmyfunction.so main.cpp name.cpp
wohu@ubuntu:~/cpp/src$
Note that the naming of dynamic link libraries and statically linked libraries are identical, but in the Linux
release system, its extension with .so
representation; Windows
system suffix .dll
.
- First use
gcc -c
instruction to specify the source files are compiled into object files, and then build a dynamic link library file from the target
Note that when the follow-up to generate dynamic link library and can be used normally, the source files are compiled into object files, also need to use the -fpic
option.
wohu@ubuntu:~/cpp/src$ g++ -c -fPIC name.cpp greeting.cpp
wohu@ubuntu:~/cpp/src$ ls
function.h greeting.cpp greeting.o libmyfunction.a main.cpp name.cpp name.o
wohu@ubuntu:~/cpp/src$
On this basis, use the object file generated in the previous step to generate a dynamic link library:
wohu@ubuntu:~/cpp/src$ g++ -shared greeting.o name.o -o libmyfunction.so
wohu@ubuntu:~/cpp/src$ ls
function.h greeting.cpp greeting.o libmyfunction.a libmyfunction.so main.cpp name.cpp name.o
wohu@ubuntu:~/cpp/src$
3.2 Use dynamic link library
Through the study in the previous chapters, we know that the use scenario of dynamic link library is to participate in linking with other source files or target files in the project. Using the previous example, for example, we will be in front greeting.cpp
, name.cpp
packed into a libmyfunction.so
dynamic link library, in which case the project remaining main.cpp
source files, so it evolved into the implementation of the demo project main.cpp
and libmyfunction.so
link, and then generate an executable file.
Note that the function.h header file does not directly participate in the compilation, because in the preprocessing stage of the program, the header files that need to be used in the project have been processed.
Execute the following instructions to successfully generate an executable file with the help of the dynamic link library:
wohu@ubuntu:~/cpp/src$ g++ main.cpp libmyfunction.so -o main
wohu@ubuntu:~/cpp/src$ ls
function.h greeting.cpp greeting.o libmyfunction.a libmyfunction.so main main.cpp name.cpp name.o
wohu@ubuntu:~/cpp/src$
Note that the generated executable files main
usually can not be directly implemented, such as:
wohu@ubuntu:~/cpp/src$ ./main
./main: error while loading shared libraries: libmyfunction.so: cannot open shared object file: No such file or directory
wohu@ubuntu:~/cpp/src$
We can see, the implementation process can not find libmyfunction.so
dynamic link library. By executing ldd main
instruction, you can view all dynamic link library file is currently in the implementation need to use, as well as the storage location of each library file:
wohu@ubuntu:~/cpp/src$ ldd main
linux-vdso.so.1 => (0x00007fffb17ea000)
libmyfunction.so => not found
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f548673a000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5486370000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f5486067000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5486abc000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f5485e51000)
wohu@ubuntu:~/cpp/src$
You can see, main
the executable file needs the support of seven dynamic link library, including libmyfunction.so
, but the file can not be found, so main
the implementation will fail.
When running the executable file generated by the dynamic link library, you must ensure that the program can find the dynamic link library when it is running. The commonly used solutions are as follows:
- The link library file to the standard library directory (eg
/usr/lib
,/usr/lib64
,/lib
,/lib64
); - Type in the terminal
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:xxx
Wherein xxx
the absolute path stored in dynamic link library file (in this embodiment is only valid in the current terminal, the terminal is invalid after closing);
- Modify
~/.bashrc
or~/.bash_profile
file, the file is added in the last line
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:xxx
Which xxx
, after an absolute path to the dynamic link library file storage, preservation, execute source bashrc
command (this way only the current logged in user valid).
In this example, the second option is used, which is to enter at the terminal
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/wohu/cpp/src
To the main
successful implementation.
wohu@ubuntu:~/cpp/src$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/wohu/cpp/src
wohu@ubuntu:~/cpp/src$ ldd main
linux-vdso.so.1 => (0x00007ffddc5fa000)
libmyfunction.so (0x00007f017bec9000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f017bb47000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f017b77d000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f017b474000)
/lib64/ld-linux-x86-64.so.2 (0x00007f017c0cb000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f017b25e000)
wohu@ubuntu:~/cpp/src$ ./main
hello,world
My name is wohu
wohu@ubuntu:~/cpp/src$