精华内容
下载资源
问答
  • 深入浅出静态链接和动态链接

    万次阅读 多人点赞 2018-05-06 09:24:48
    作为一名C/C++程序员,对于编译链接的过程要了然于胸。首先大概介绍一下,编译分为3步,首先对源文件进行预处理,这个过程主要是处理一些#号定义的命令或语句(如宏、#include、预编译指令#ifdef等),生成*.i文件;...

            作为一名C/C++程序员,对于编译链接的过程要了然于胸。首先大概介绍一下,编译分为3步,首先对源文件进行预处理,这个过程主要是处理一些#号定义的命令或语句(如宏、#include、预编译指令#ifdef等),生成*.i文件;然后进行编译,这个过程主要是进行词法分析、语法分析和语义分析等,生成*.s的汇编文件;最后进行汇编,这个过程比较简单,就是将对应的汇编指令翻译成机器指令,生成可重定位的二进制目标文件。以上就是编译的过程,下面主要介绍两种链接方式--静态链接和动态链接。

            静态链接和动态链接两者最大的区别就在于链接的时机不一样,静态链接是在形成可执行程序前,而动态链接的进行则是在程序执行时,下面来详细介绍这两种链接方式。

    一、静态链接

    1.为什么要进行静态链接

            在我们的实际开发中,不可能将所有代码放在一个源文件中,所以会出现多个源文件,而且多个源文件之间不是独立的,而会存在多种依赖关系,如一个源文件可能要调用另一个源文件中定义的函数,但是每个源文件都是独立编译的,即每个*.c文件会形成一个*.o文件,为了满足前面说的依赖关系,则需要将这些源文件产生的目标文件进行链接,从而形成一个可以执行的程序。这个链接的过程就是静态链接

    2.静态链接的原理

             由很多目标文件进行链接形成的是静态库,反之静态库也可以简单地看成是一组目标文件的集合,即很多目标文件经过压缩打包后形成的一个文件,如下图,使用ar命令的-a参数查看静态库的组成:


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

            以下面这个图来简单说明一下从静态链接到可执行文件的过程,根据在源文件中包含的头文件和程序中使用到的库函数,如stdio.h中定义的printf()函数,在libc.a中找到目标文件printf.o(这里暂且不考虑printf()函数的依赖关系),然后将这个目标文件和我们hello.o这个文件进行链接形成我们的可执行文件。


            这里有一个小问题,就是从上面的图中可以看到静态运行库里面的一个目标文件只包含一个函数,如libc.a里面的printf.o只有printf()函数,strlen.o里面只有strlen()函数。

            我们知道,链接器在链接静态链接库的时候是以目标文件为单位的。比如我们引用了静态库中的printf()函数,那么链接器就会把库中包含printf()函数的那个目标文件链接进来,如果很多函数都放在一个目标文件中,很可能很多没用的函数都被一起链接进了输出结果中。由于运行库有成百上千个函数,数量非常庞大,每个函数独立地放在一个目标文件中可以尽量减少空间的浪费,那些没有被用到的目标文件就不要链接到最终的输出文件中。

    3.静态链接的优缺点

            静态链接的缺点很明显,一是浪费空间,因为每个可执行程序中对所有需要的目标文件都要有一份副本,所以如果多个程序对同一个目标文件都有依赖,如多个程序中都调用了printf()函数,则这多个程序中都含有printf.o,所以同一个目标文件都在内存存在多个副本;另一方面就是更新比较困难,因为每当库函数的代码修改了,这个时候就需要重新进行编译链接形成可执行程序。但是静态链接的优点就是,在可执行程序中已经具备了所有执行程序所需要的任何东西,在执行的时候运行速度快。

    问题:

    二、动态链接
    1.为什么会出现动态链接

            动态链接出现的原因就是为了解决静态链接中提到的两个问题,一方面是空间浪费,另外一方面是更新困难。下面介绍一下如何解决这两个问题。

    2.动态链接的原理

            动态链接的基本思想是把程序按照模块拆分成各个相对独立部分,在程序运行时才将它们链接在一起形成一个完整的程序,而不是像静态链接一样把所有程序模块都链接成一个单独的可执行文件。下面简单介绍动态链接的过程:

            假设现在有两个程序program1.o和program2.o,这两者共用同一个库lib.o,假设首先运行程序program1,系统首先加载program1.o,当系统发现program1.o中用到了lib.o,即program1.o依赖于lib.o,那么系统接着加载lib.o,如果program1.o和lib.o还依赖于其他目标文件,则依次全部加载到内存中。当program2运行时,同样的加载program2.o,然后发现program2.o依赖于lib.o,但是此时lib.o已经存在于内存中,这个时候就不再进行重新加载,而是将内存中已经存在的lib.o映射到program2的虚拟地址空间中,从而进行链接(这个链接过程和静态链接类似)形成可执行程序。

    3.动态链接的优缺点

            动态链接的优点显而易见,就是即使需要每个程序都依赖同一个库,但是该库不会像静态链接那样在内存中存在多分,副本,而是这多个程序在执行时共享同一份副本;另一个优点是,更新也比较方便,更新时只需要替换原来的目标文件,而无需将所有的程序再重新链接一遍。当程序下一次运行时,新版本的目标文件会被自动加载到内存并且链接起来,程序就完成了升级的目标。但是动态链接也是有缺点的,因为把链接推迟到了程序运行时,所以每次执行程序都需要进行链接,所以性能会有一定损失。

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

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

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

    展开全文
  • 静态链接和动态链接两者最大的区别就在于链接的时机不一样,静态链接是在形成可执行程序前,而动态链接的进行则是在程序执行时,下面来详细介绍这两种链接方式。 静态链接的优缺点 静态链接的缺点很明显,一是浪费...

    静态连接和动态链接的区别

    静态链接和动态链接两者最大的区别就在于链接的时机不一样,静态链接是在形成可执行程序前,而动态链接的进行则是在程序执行时,下面来详细介绍这两种链接方式。

    静态链接的优缺点

    静态链接的缺点很明显,一是浪费空间,因为每个可执行程序中对所有需要的目标文件都要有一份副本,所以如果多个程序对同一个目标文件都有依赖,如多个程序中都调用了printf()函数,则这多个程序中都含有printf.o,所以同一个目标文件都在内存存在多个副本;另一方面就是更新比较困难,因为每当库函数的代码修改了,这个时候就需要重新进行编译链接形成可执行程序。但是静态链接的优点就是,在可执行程序中已经具备了所有执行程序所需要的任何东西,在执行的时候运行速度快。

    动态链接的优缺点 

    动态链接的优点显而易见,就是即使需要每个程序都依赖同一个库,但是该库不会像静态链接那样在内存中存在多分,副本,而是这多个程序在执行时共享同一份副本;另一个优点是,更新也比较方便,更新时只需要替换原来的目标文件,而无需将所有的程序再重新链接一遍。当程序下一次运行时,新版本的目标文件会被自动加载到内存并且链接起来,程序就完成了升级的目标。但是动态链接也是有缺点的,因为把链接推迟到了程序运行时,所以每次执行程序都需要进行链接,所以性能会有一定损失。
    ————————————————
    版权声明:本文为CSDN博主「kang___xi」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/kang___xi/article/details/80210717 

    展开全文
  • 在理解静态和动态(共享)库链接之间的区别之前,让我们先看一个典型程序的生命周期。从编写源代码到执行它。首先使用任何程序员选择的编辑器以文本文件的形式编写程序,然后必须对其进行编译以将文本文件转换为机器...

    在理解静态和动态(共享)库链接之间的区别之前,让我们先看一个典型程序的生命周期。从编写源代码到执行它。首先使用任何程序员选择的编辑器以文本文件的形式编写程序,然后必须对其进行编译以将文本文件转换为机器可以理解和执行的目标代码。

    通常我们编写的程序可能会使用其他程序或程序库。 我们编写的程序必须与这些其他程序或库一起才能执行。

    链接是将我们编写的外部程序成功执行所需的外部程序组合在一起的过程。 静态链接和动态链接是收集和组合多个目标文件以创建单个可执行文件的两个过程。 在这里,我们将讨论它们之间的区别

    链接可以在两次编译时执行:当源代码翻译成机器代码时; 或将程序加载到内存中时,甚至在运行时由应用程序加载。 它由称为链接器的程序执行。链接器也称为链接编辑器。 链接是编译程序的最后一步。

    链接后,要执行该组合程序,必须将其移入内存。为此,必须为数据和指令分配地址以执行程序。 以上过程可以概括为程序生命周期(写->编译->链接->加载->执行)。

    以下是静态链接和动态链接之间的主要区别:
    (1)静态链接是将程序中使用的所有库模块复制到最终可执行映像中的过程。 这是由链接器执行的,并且是编译过程的最后一步。 链接器将库例程与程序代码结合在一起,以便解析外部引用,并生成适合装入内存的可执行映像。 加载程序后,操作系统会将包含可执行代码和数据的单个文件放入内存。 该静态链接文件包括调用程序和被调用程序。
    在动态链接中,外部库(共享库)的名称放置在最终的可执行文件中,而实际链接是在运行时将可执行文件和库都放置在内存中时进行的。 动态链接使多个程序可以使用可执行模块的单个副本。
    (2)静态链接由链接程序执行,是编译程序的最后一步。 链接器也称为链接编辑器。动态链接由操作系统在运行时执行。
    (3)静态链接文件的大小明显更大,因为外部程序内置在可执行文件中。
    在动态链接中,共享库中只有一个副本保留在内存中。 这大大减小了可执行程序的大小,从而节省了内存和磁盘空间。
    (4)在静态链接中,如果任何外部程序已更改,则必须重新编译并重新链接它们,否则更改将不会反映在现有的可执行文件中。
    在动态链接中不是这种情况,可以更新和重新编译各个共享模块。 这是动态链接所提供的最大优势之一。
    (5)静态链接的程序每次将其加载到内存中执行时,都会花费恒定的加载时间。
    在动态链接中,如果共享库代码已存在于内存中,则可以减少加载时间。
    (6)使用静态链接库的程序通常比使用共享库的程序快。
    使用共享库的程序通常比使用静态链接库的程序要慢。
    (7)在静态链接程序中,所有代码都包含在一个可执行模块中。 因此,它们永远不会遇到兼容性问题。
    动态链接的程序依赖于具有兼容的库。 如果更改了库(例如,新的编译器版本可能更改了库),则可能必须重新设计应用程序以使其与该库的新版本兼容。 如果从系统中删除了一个库,则使用该库的程序将不再起作用。

    展开全文
  • 静态链接和动态链接区别

    万次阅读 2019-09-22 22:17:18
    在链接过程中,静态链接和动态链接就出现了区别。静态链接的过程就已经把要链接的内容已经链接到了生成的可执行文件中,就算你在去把静态库删除也不会影响可执行程序的执行;而动态链接这个过程却没有把内容链接...

     1.静态链接与动链接的区别

            在C语言中,我们知道要生成可执行文件,必须经历两个阶段,即编译、链接。

            在编译过程中,只有编译,不会涉及到链接。

               在链接过程中,静态链接和动态链接就出现了区别。静态链接的过程就已经把要链接的内容已经链接到了生成的可执行文件中,就算你在去把静态库删除也不会影响可执行程序的执行;而动态链接这个过程却没有把内容链接进去,而是在执行的过程中,再去找要链接的内容,生成的可执行文件中并没有要链接的内容,所以当你删除动态库时,可执行程序就不能运行。

               所以总的来说,动态链接生成的可执行文件要比静态链接生成的文件要小一些。

    2.动态库与静态库的区别

            2.1就不设置环境变量的情况下来说

            动态库一般都会存在/usr/lib/ 目录下;而静态库可以在任何目录下,只要你第一次链接的时候,用绝对路径去链接就行了,之后再删除,是不会影响你的生成的执行文件的。

                2.2如若可以设置环境变量的话

                动态库和静态库可以放置到你想放的任何地方,只是动态库需要设置环境变量,而静态库链接的时候需要绝对路径。

                但一般来说,动态库都会放在放在/usr/lib,应该大家都习惯了,这样也方便寻找,而当链接动态库的时候默认的路径就是/usr/lib。

    各自的优缺点:

    1、静态链接库执行速度比动态链接库快。(执行过程不需要找链接的内容)

    2、动态链接库更节省内存。(未写入要链接的内容)

    展开全文
  • 静态链接和动态链接及其区别

    千次阅读 2020-01-11 23:11:24
    我们知道编译器会将程序源文件编译成一个个目标文件,并最终链接成可执行程序或者静态库或动态库,静态库一般都是指的由静态链接的目标文件集合,而动态库一般是动态链接目标生成的目标集合,那么静态链接和动态链接...
  • 静态链接 :不同的程序开发者部门能够相对独立地开发测试自己的程序模块,大大促进了程序开发效率。 优点: 代码装载速度快,执行速度略比动态链接库快; 只需保证在开发者的计算机中有正确的.LIB文件,在以二...
  • 程序的运行过程分为两个阶段,分别为编译阶段和链接阶段,而编译阶段又分为三部分:预编译,编译,汇编 预编译(生成.i文件) 展开头文件,宏替换,条件编译,去掉注释 编译(生成.s文件) 检查错误,...
  • 本文详细介绍了静态链接库与动态链接库的区别,适合于那些对二者概念分不清楚的同学,以及如何创建一个静态库和动态库的方法
  • linux下的静态链接和动态链接(一)

    千次阅读 2018-05-21 21:46:27
    静态链接静态链接就是,在生成可执行程序的时候,把目标文件.o 静态库 .a ,使用 ld 链接器,链接生成一个可执行程序。这是在程序加载前就完成的动作。 动态链接:动态链接就是,在生成可执行程序的时候,只是...
  • 静态链接库的优点 代码装载速度快,执行速度略比动态链接库快; 只需保证在开发者的计算机中有正确的.LIB文件,在以二进制形式发布程序时不需考虑在用户的计算机上.LIB文件是否存在及版本问题,可避免DLL地狱等...
  • 在JVM的静态链接和动态链接.pdf
  • 根据链接时期的不同,库又有静态和动态库之分,有别于静态库,动态库的链接是在程序执行的时候被链接
  • 【转载】c++ 静态链接和动态链接

    千次阅读 2018-01-02 14:32:36
    C++静态库与动态库 ...这里不深入介绍静态库、动态库的底层格式,内存布局等,有兴趣的同学,推荐一本书《程序员的自我修养——链接、装载与库》。 什么是库 库是写好的现有的,成熟的,可以复
  • 之前一直不是很理解静态链接和动态连接库的区别,今天在此做一下汇总。首先从下图了解一下文本文件是如何编译成二进制格式的。 【静态链接库】是指在编译的连接阶段将库函数嵌入到应用系统程序的内部。但是如何...
  • 程序运的动态链接和静态链接的区别,可以看下。。
  • Linux-动态链接与静态链接对比(动态静态库)

    千次阅读 多人点赞 2017-12-14 17:52:46
    一、库的基础概念: 在windows平台linux平台下都大量存在着库。本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。...按照库的使用方式又可分为动态和静态库,在不同平台下...
  • 静态链接动态链接的区别使用

    万次阅读 多人点赞 2018-11-27 13:34:59
     静态链接:譬如让书本白板上的笔记之间做静态链接,就是把白板上的笔记抄在书上书笔记形成一个整体(可执行程序),这个时候把白板上的内容擦掉也没关系,因为已经整合到书上了。静态链接的优点是“效率高”...
  • 下面小编就为大家带来一篇浅谈CMake配置OpenCV 时静态链接动态链接的选择。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 动态链接库和静态链接库区别,让你真正理解动态链接库和静态链接库的区别。
  • 静态连接就是把外部函数库,拷贝到可执行文件中。 优点:适用范围比较广,不用担心用户机器缺少某个库文件; 缺点:安装包会比较大,而且多个应用程序之间,无法共享库文件。 动态连接的做法正好相反,外部...
  • 静态链接库的使用需要库的...静态链接库与动态链接库都是共享代码的方式,静态链接和动态链接库的区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态静态链接库。
  • 1.1、当我们建立一个项目(应用程序)它可以有很多种生成类型(应用程序.exe、动态库.dll、静态库lib),可以在创建向导时指定也可以在配置属性里更改。以vs2010为例,右键点击项目属性->配置属性->右侧配置类型中...
  • 写程序时,在开发的linux平台编译的程序,到了测试的linux平台往往不能使用,大部分是由于glibc的版本存在差异导致的,为了解决glibc版本兼容的问题,可以使用静态链接的方式链接glibc相关的库,但同时也会遇到需要...
  • 静态链接使得不同的程序开发者部门能够相对独立地开发测试自己的程序模块,从某种意义上来讲大大促进了程序开发的效率,原先限制程序的规模也随之扩大。但是慢慢地静态链接的诸多缺点也逐步暴露出来,比如浪费...
  • 对于一个静态链接库L.lib,它的使用者app.exe会静态链接L.lib,意思是app.exe会将L.lib中的代码(app需要的部分,例如函数定义,类的定义等等)链接到app.exe中.  而对于L.lib本身来说,它的CRT(C Run-Time Libraries)...
  • 链接器之静态链接动态链接

    千次阅读 2017-04-23 20:20:21
    最近在项目中需要用一个公司的CAN卡,然后到官网下载官方提供的库文件,下载下来的有3个文件.h、.lib、.dll,OK,现在主角出现了,.lib.dll。 其实一般的库文件都包含了这三个文件,无奈自己接触的还是比较少,...
  • ldd a.out 查看依赖的库文件(动态和静态库都可以看到)
  • 静态链接和动态链接

    2013-09-16 11:32:50
    大家都知道应用程序有两种链接方式,一种是静态链接,一种是动态链接,这两种链接方式各有好处。 程序的静态连接还是动态连接是根据编译器的连接参数指定的。 所谓静态链接就是在编译链接时直接将需要的执行代码...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 538,119
精华内容 215,247
关键字:

静态链接和动态链接