下面小编就来介绍一下C的静态链接和动态链接。我觉得边肖挺好的。我现在就分享给你,给你一个参考。来和边肖一起看看吧。
:
目录
1.GCC工作流程2。静态链接和动态链接1。静态链接2。动态链接摘要
一、GCC工作流程
预处理:展开#头文件,替换宏,并删除注释(生成。I文件)
编译:将预处理文件生成为汇编文件(。s文件),主要是检查语法和语义。
汇编:将装配文件生成为目标文件(。o文件)
链接:将函数库中相应的代码合并到目标文件中,生成一个可执行文件(默认为a.out文件)
o文件不会被立即执行,因为它可能发生:一个函数中的一个。cpp文件引用了另一个文件中定义的符号。cpp文件/调用库文件中的函数。链接的目的是将这些文件对应的目标文件链接成一个整体,从而生成可执行文件。
二、静态链接与动态链接
库:包含数据和执行代码的文件,不能单独执行,但可以作为库的一部分来完成一些功能。
库的存在可以模块化程序,加快程序的重编译,实现代码重用,方便程序更新。
库分为静态链接库和动态链接库。
1、静态链接
在链接阶段。将汇编生成的o文件和所需的库链接打包成可执行文件,程序运行时不会调用其他库文件。
一个静态库,可以看作是一些目标代码的集合,在可执行程序运行之前,已经被添加到可执行代码中,成为可执行程序的一部分。
静态链接的优点:对运行环境的依赖性更小,兼容性更好。
静态链接的缺点:生成的程序更大,需要更多的系统资源(所有需要的库都打包成可执行文件),加载内存消耗更多的时间。
一旦库函数更新,应用程序必须重新编译。
这里我们做一个静态库,实现加减乘除。首先,我们编写add.c、sub.c、mul.c、div.c文件以及它们对应的。h文件,然后我们写text.c文件进行测试。Gcc -c生成目标文件。o,然后将。o文件来创建静态库libtext.a
2、动态链接
静态库存在的问题:
(1)如果两者都有。o文件使用同一个静态库,那么两个静态库的代码会被复制到内存中,然后和两个一起打包成可执行文件。o文件,造成空间浪费。
例如,一个静态库占用1M内存,而2000。o文件使用这个静态库。内存中有2000个静态库代码(近2000GB),浪费了大量空间。
(2)所需的库已经复制到可执行文件中。如果一个库被更新,所有与之相关的可执行文件都需要重新编译。
为了解决这两个问题,引入了动态库(也称共享库)。程序编译时,动态库不会链接到目标代码,而是在运行时加载。如果不同的应用程序调用同一个库,那么在内存中只有一个共享库的实例,从而避免了浪费。因为动态库是在运行时加载的,所以也解决了静态库更新、部署、发布程序带来的马粪问题。用户只需要更新动态库。
动态链接的优点:链接时,只建立与所需库函数的关系;
在程序运行时,将所需资源调用到可执行程序中;
简化程序升级,程序体积更小;
实现进程间资源共享,内存中只有一个动态库实例,避免完全复制。
动态链接的缺点:依赖于动态库,不能独立运行。
动态库依赖版本问题严重。
同样,我们做一个动态库,实现加减乘除。
我们复制动态库。所以还有测试文件。c到当前目录,这样系统在加载可执行文件的时候,就可以知道它所依赖的库的名字,但是也需要找到动态库的绝对路径。这时候就需要系统动态链接器/加载器了。elf格式的可执行程序由ld-linux.so*完成。搜索elf文件的DT_PATH段(环境变量)LD_LIBRARY_PATH、/etc/ld.so.cache文件列表和/urs/lib目录。找到库文件并将其加载到内存中。
动态库加载失败的解决方法:这里有两种方法可以找到动态库。
总结
本文到此为止。希望能帮到你,也希望你能多关注我们的更多内容!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。