动态、静态:指的是链接过程如何处理库;
静态库
静态库(函数库)对程序的影响是在编译时就产生的,在编译时会将静态库的代码拷贝到目标程序中。
缺点:浪费空间和资源,所有相关的目标文件与牵涉到的函数库都被链接为一个文件,每个用到了该函数库的程序都存在一份一模一样的函数库内容、程序更新意味着整个程序均发生全量更新。
动态库
在程序编译时不会被链接到目标代码中,而是在程序运行时才被载入。
其在内存中只存在一份拷贝,就像是一个家政公司,需要使用该函数的程序共享即可,极大节省了空间资源。
jiaming@ubuntu:~/Documents/test3$ cat hello.h
void hello(const char* name);
jiaming@ubuntu:~/Documents/test3$ cat hello.c # 待封装的库程序
void hello(const char* name)
{
printf("hello %s! \n", name);
}
jiaming@ubuntu:~/Documents/test3$ cat main.c # 可以直接调用库程序中的函数
int main()
{
hello("my friends.");
return 0;
}
1. 将多个源文件编译链接为一个可执行文件
jiaming@ubuntu:~/Documents/test3$ tree .
.
├── hello.c
├── hello.h
└── main.c
0 directories, 3 files
jiaming@ubuntu:~/Documents/test3$ sudo gcc -c hello.c main.c
jiaming@ubuntu:~/Documents/test3$ ls
hello.c hello.h hello.o main.c main.o
jiaming@ubuntu:~/Documents/test3$ sudo gcc -o hello hello.o main.o
jiaming@ubuntu:~/Documents/test3$ sudo chmod +x hello
jiaming@ubuntu:~/Documents/test3$ ./hello
hello my friends.!
2. 创建静态链接库 lib,使用 main 函数调用 hello 函数可调用静态链接库
jiaming@ubuntu:~/Documents/test4$ ls
hello.c hello.h main.c
jiaming@ubuntu:~/Documents/test4$ sudo gcc -c hello.c
jiaming@ubuntu:~/Documents/test4$ ls
hello.c hello.h hello.o main.c
jiaming@ubuntu:~/Documents/test4$ sudo ar crv libxxxx.a hello.o
a - hello.o
jiaming@ubuntu:~/Documents/test4$ ls
hello.c hello.h hello.o libxxxx.a main.c
jiaming@ubuntu:~/Documents/test4$ sudo gcc -o out main.c -L./ -lxxxx # -l参数后面紧跟着程序需要链接的静态库名,将库文件名的头lib和尾.so/.a 去掉即可。 -L参数后面紧跟着库文件的路径。放在/lib、/usr/lib、/usr/local/lib里的库直接用-l参数即可链接,否则用-L参数指定位置。
jiaming@ubuntu:~/Documents/test4$ ls
out hello.c hello.h hello.o libxxxx.a main.c
jiaming@ubuntu:~/Documents/test4$ ./out
hello my friends.!
3. 动态库
在程序运行时,才会去指定的三个地方加载库程序链接运行。
jiaming@ubuntu:~/Documents/test5$ ls
hello.c hello.h main.c
jiaming@ubuntu:~/Documents/test5$ sudo gcc -shared -fPIC -o libxxxx.so hello.c # -shared 指定生成动态链接库、-fPIC 创建与系统无关的编译程序,实现多个程序共享
jiaming@ubuntu:~/Documents/test5$ ls
hello.c hello.h libxxxx.so main.c
jiaming@ubuntu:~/Documents/test5$ gcc main.c -L. -lxxxx
jiaming@ubuntu:~/Documents/test5$ ls
a.out hello.c hello.h libxxxx.so main.c
jiaming@ubuntu:~/Documents/test5$ ./a.out # 并不能直接运行,原因在于动态链接时仅仅会从三个默认的地方去找动态链接库
./a.out: error while loading shared libraries: libxxxx.so: cannot open shared object file: No such file or directory
jiaming@ubuntu:~/Documents/test5$ sudo cp libxxxx.so /usr/local/lib/ # 貌似拷贝到这个位置也不行 /usr/local/lib/
jiaming@ubuntu:~/Documents/test5$ ./a.out
./a.out: error while loading shared libraries: libxxxx.so: cannot open shared object file: No such file or directory
jiaming@ubuntu:~/Documents/test5$ sudo mv libxxxx.so /lib # 拷贝到 /lib 下可以
jiaming@ubuntu:~/Documents/test5$ ./a.out
hello my friends.!