什么是库
库是为了实现代码重用和模块化而创建的代码集合,而静态库和动态库则是库的两种主要形式,它们在编译和链接过程中有不同的处理方式和使用方式。
源代码如上图所示,通过编译生成a.out
可执行文件,我们可以使用lld查看可执行文件所依赖的动态库。
关于ldd
ldd是Linux中的一个重要命令,用于打印可执行文件或共享库所依赖的动态链接库信息。这个命令会递归地检查文件所依赖的所有库,并显示它们的路径。
使用ldd命令,你可以了解一个程序运行所需的库文件,以及这些库文件是否存在、版本是否匹配等信息。如果某个动态链接库无法找到,ldd命令会显示"not found"。
在解决依赖关系问题时,ldd命令是一个很有用的工具。你可以通过安装相应的软件包或手动将缺失的动态链接库复制到系统的标准库路径下来解决这些问题。另外,使用静态链接、容器技术或静态库也是解决依赖关系问题的有效方法。
可以看到上述的libc.so.6就是这个可执行文件所依赖的共享库之一。
这是一个ELF格式的共享库文件。
实际上,编译的时候,对于c库,编译器会默认以动态链接的方式进行链接,即只是在链接的时候在对应的可执行文件记录下对应的信息(表明这些符号属于动态库),知道真正调用的时候才去加载。
我们可以尝试将可执行文件进行静态链接,如下:
可以看到静态编译的结果要比动态编译生成的可执行文件大得多。这样有好处也有坏处,具体的在后面会说明。
静态库的制作与使用
什么是静态库呢?静态库是一种编译后的代码和数据集合(本质是可重定位目标文件),通常以文件的形式存在,可以被其他程序在编译时静态地链接和使用。静态库中的代码和数据会被直接嵌入到最终的可执行文件中,因此,最终程序在运行时不再需要静态库本身。
静态库的命名:libxxx.a xxx就是静态库的名字
下面是生成静态库的流程:
动态库的制作与使用
动态库(Dynamic Link Library)又称动态链接库,英文缩写为DLL。它是一个包含可由多个程序同时使用的代码和数据的库,但这些库不是可执行文件。动态库提供了一种方法,使得进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个DLL中,该DLL包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。DLL还有助于共享数据和资源,多个应用程序可同时访问内存中单个DLL副本的内容。
此外,使用动态库还可以提高程序的可维护性和可扩展性。因为当动态库中的代码需要更新或修复时,只需要替换相应的动态库文件,而不需要重新编译和链接整个程序。这大大简化了程序的维护和升级过程。同时,通过添加新的动态库,还可以为程序添加新的功能和特性,而不需要修改程序的源代码。
在Linux中,动态库命名为libxxx.so,xxx为动态库的名字。、
在实际生产中,链接时的动态库是一个符号链接,指向一个实际的动态库,这样的好处是可以升级方便,而不用重新去链接代码
总结
库文件可以看作是轮子,公共的文件,特殊的.o文件,使他人写好的公开发行的
主要分为静态库以及动态库
动态库和静态库是两种常见的库类型,它们在编译方式、内存使用、更新和维护方式等方面有明显的区别。
- 编译方式:
动态库是在程序运行时动态加载的库,可以在程序运行时被链接和调用。而静态库是在程序编译时被打包到可执行文件中的库,可以直接被调用和访问。 - 内存使用:
由于静态库被打包到可执行文件中,因此在程序运行时,静态库中的代码会被复制到程序使用的内存中,一直驻留并被使用。而动态库在程序运行时才会被加载到内存中,因此其内存使用方式更加灵活,可以节省内存空间。 - 更新和维护方式:
静态库在编译时被打包到可执行文件中,因此如果需要更新静态库,需要重新编译程序。而动态库可以独立于程序进行更新,当动态库更新时,只需要替换掉旧的动态库文件,而不需要重新编译程序。
综上所述,动态库和静态库有明显的区别,需要根据具体的应用场景选择合适的库类型。如果需要程序的可执行文件独立于库文件运行,并且需要灵活的内存使用方式,可以选择使用动态库。如果需要程序在编译后即可独立运行,并且需要简单的更新和维护方式,可以选择使用静态库。
特点 | 产品大小 | 部署难度 | 升级 |
静态库 | 大 | 简单 | 复杂 |
动态库 | 小 | 复杂 | 容易 |