静态链接库解决了代码复用性的问题,

静态:以lib开头,扩展名是.a文件,在/usr/lib目录下。

动态:以lib开头,扩展名是.so文件,

一、静态链接库

静态库解决了代码复用的问题。静态库文件,是将所有相关的函数编译成独立的目标模块,再用ar命令封装而成的一个单独的文件。

在Linux系统上,它以lib开头,扩展名是.a。在/usr/lib目录下,可以找到一些静态库文件:

gcc/x86_64-linux-gnu/13/libasan.a

gcc/x86_64-linux-gnu/13/libgomp.a

gcc/x86_64-linux-gnu/13/libstdc++.a

x86_64-linux-gnu/libm.a

x86_64-linux-gnu/libcrypt.a

x86_64-linux-gnu/libc.a

libc.a封装了所有程序都可用的标准I/O、字符串操作和整数数学函数;

libm.a封装了浮点数学函数;

libgomp.a封装了支持openmp和openacc编程导语的并行编程操作;

libcrypt.a封装了加解密操作。

可以试着使用ar x libc.a命令,抽取一下libc.a包含的.o文件看下

样例

1.提供向量的加和乘操作的静态库libvector.a

2.main2.c,需要调用向量加操作完成自己的功能,然后给用户打印相关的提示信息。

3.Main2.c通过翻译器转换成可重定位的目标文件main2.o

4.当链接器ld运行时,它判定main2.o运用了addvec.o定义的向量加符号,所以,复制addvec.o到可执行文件prog2。因为涉及到打印,还会复制printf.o等模块。

5.因为不涉及到向量乘,所以链接器ld不会复制multvec.o到可执行文件。

静态链接库像粘合在一起的拼图块。当链接器发现应用程序需要静态链接库里面的拼图块的时候,就从拼图块中拿下一块来组组装起来,组装完成应用程序功能拼图。

二、动态链接库

        静态链接库解决了代码复用性的问题,但是它也有明显的缺点 。      

         静态链接库是将库中的目标文件复制到程序中生成的。对于基础函数,如打印等,每个程序都要用,因此它会被复制到很多程序中,这样在存储时浪费了磁盘空间,另外在运行时也对内存形成了浪费。

        动态链接库技术。1984 年 SunOS 4.0 推出 ELF 与 ld.so 的完整实现,首次提出PIC(位置无关代码)、延迟绑定(lazy binding),1985 年 AT&T System V R3 把 ELF+动态库规格化,随后 BSD、Solaris、Linux 全线跟进。

        

动态链接库也叫共享库(shared library),共享目标(shared object),在linux系统上,是以lib开头,.so为扩展名的文件。比如:

bfd-plugins/liblto_plugin.so

gcc/x86_64-linux-gnu/13/libgcc_s.so

gcc/x86_64-linux-gnu/13/libstdc++.so

gcc/x86_64-linux-gnu/13/libtsan.so

gcc/x86_64-linux-gnu/13/libgomp.so

python3/dist-packages/netplan/_netplan_cffi.abi3.so

python3/dist-packages/_dbus_glib_bindings.cpython-312-x86_64-linux-gnu.so

python3/dist-packages/gi/_gi.cpython-312-x86_64-linux-gnu.so

x86_64-linux-gnu/libm.so

x86_64-linux-gnu/libthread_db.so

x86_64-linux-gnu/libmvec.so

动态链接库可以在运行或者加载时,被加载到任意内存地址,并和一个在内存中的程序链接起来。这个过程由动态链接器执行,被称为动态链接

动态链接库的共享性体现在两个地方:

1.一个库只有一个so,所有引用该库的程序共享这个so中的代码和数据

这点和静态库被嵌入到到每个应用程序不同。因此它能节约磁盘空间

参考:

《深入理解计算机系统》

更多推荐