首页 > 编程知识 正文

动态链接和静态链接区别,动态链接 静态链接

时间:2023-05-03 10:44:21 阅读:178093 作者:27

作为C/C程序员,对编译链接的过程应该在心里熟悉。 首先大致说明一下,编译分为三个步骤,首先预处理源文件。 该过程主要处理#号定义的命令和语句,如宏、#include和预编译命令#ifdef,并生成*.i文件。 然后进行编译,该过程主要进行词法分析、语法分析、语义分析等,生成*.s的汇编文件; 最后进行汇编。 该过程相对简单,将对应的汇编指令翻译成机器指令,生成可重定位的二进制目标文件。 以上就是编译的过程。 主要介绍静态链接和动态链接这两种链接方式。

静态链接和动态链接的最大区别在于链接的定时不同。 静态链接在可执行文件形成之前,动态链接的进度是在程序运行时。 以下详细说明这两种链接方式。

一、静态链接1 .为什么要进行静态链接在我们的实际开发中,不可能把所有的代码都放在一个源文件里,所以会出现多个源文件。 此外,多个源文件之间存在多个依赖关系,而不是独立的。 例如,一个源文件可能会调用在另一个源文件中定义的函数,但每个源文件都是独立编译的。 这意味着每个*.c文件都形成一个*.o文件。 为了满足上述依赖关系,此链接的过程是静态链接

2 .静态链接的原理很多目标文件链接在一起形成的是静态库,相反,静态库也可以仅仅看作是目标文件的集合。 也就是说,它是由许多目标文件压缩打包而成的一个文件。 如下图所示,使用ar命令的-a参数来查看静态库的配置。

这里的*.o目标文件在我之前的博客《从编写源代码到程序在内存中运行的全过程解析》上已经说得很清楚了,不清楚的人可以读一下。

下图简要说明了从静态链接到可执行文件的过程。 基于包含在源文件中的头部文件和程序中使用的库函数(例如在stdio.h中定义的printf ) )函数,在libc.a中找到目标文件的printf.o,在此为PPT 然后,我们把这个目标文件和我们hellintf )函数

这里有个小问题。 如上图所示,静态运行库中的一个目标文件只包含一个函数。 例如,libc.a中的printf.o只包含printf (函数),而strlen.o只包含strlen (函数)。

链接静态链接库时,您知道链接器是目标文件单位。 例如,如果引用静态库中的printf ) )函数,链接器将链接包含该函数的目标文件。 如果许多函数都位于一个目标文件中,则许多无用的函数很可能会链接到输出结果。 运行时库包含数百个函数,数量非常庞大,因此通过将每个函数独立放在一个目标文件中,可以最大限度地减少空间浪费。 不要将未使用的目标文件链接到最终的输出文件。

3 .静态链路的优缺点静态链路的缺点很明显,一是浪费空间。 由于每个可执行文件都需要复制所有必需的目标文件,因此如果多个程序依赖于同一目标文件,则多个程序将包含printf (如果调用函数,则这些程序将包含printf.o ) 另一方面,更新之所以困难,是因为每当库函数的代码被修正时,就需要重构编译链接并形成可执行程序。 但是,静态链接的优点是,可执行程序具备执行程序所需的一切,执行时的执行速度快。

问题:

二.动态链接

1 .出现动态链路的动态链路的原因是为了解决静态链路中提到的两个问题,这既浪费空间,又很难更新。 介绍解决这两个问题的方法。

2 .动态链接的原理动态链接的基本思想是,不像静态链接那样将所有的程序模块链接到单独的可执行文件上,而是将程序分割为每个模块独立的部分,在程序运行时将它们链接到一个完整的程序上简单说明动态链接的过程。

假设您目前有两个程序program1.o和program2.o,它们共享同一个库lib.o。 首先运行程序program1,系统首先加载program1.o,当系统发现program1.o中使用了lib.o,即program1.o时,program2正在运行虽然发现program2.o依存于lib.o,但此时lib.o已经存在于内存中,此时不进行重新加载,而是将内存中已经存在的lib.o映射到program2的虚拟地址空间进行链接

3 .动态链接的优点和缺点动态链接的优点很明显,即使各程序需要依赖同一个程序库,该程序库也不像静态链接那样在内存中存在多个点、副本,而是这些多个程序在运行时共享同一个副本另一个优点是

,更新也比较方便,更新时只需要替换原来的目标文件,而无需将所有的程序再重新链接一遍。当程序下一次运行时,新版本的目标文件会被自动加载到内存并且链接起来,程序就完成了升级的目标。但是动态链接也是有缺点的,因为把链接推迟到了程序运行时,所以每次执行程序都需要进行链接,所以性能会有一定损失。

        据估算,动态链接和静态链接相比,性能损失大约在5%以下。经过实践证明,这点性能损失用来换区程序在空间上的节省和程序构建和升级时的灵活性是值得的。

4.动态链接地址是如何重定位的呢?

        前面我们讲过静态链接时地址的重定位,那我们现在就在想动态链接的地址又是如何重定位的呢?虽然动态链接把链接过程推迟到了程序运行时,但是在形成可执行文件时(注意形成可执行文件和执行程序是两个概念),还是需要用到动态链接库。比如我们在形成可执行程序时,发现引用了一个外部的函数,此时会检查动态链接库,发现这个函数名是一个动态链接符号,此时可执行程序就不对这个符号进行重定位,而把这个过程留到装载时再进行。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。