首页 > 代码库 > 程序员的自我修养-链接、装载与库-7 动态链接

程序员的自我修养-链接、装载与库-7 动态链接

动态链接

静态链接的好处:使得不同部门的开发者能够相对独立的开发和测试自己的程序模块,促进了开发效率,原先限制程序的规模也随之扩大。

     缺点:浪费内存空间和磁盘空间,模块更新困难

  种种罪行:

  空间浪费:想想一下每个程序内部除了printf, scanf, strlen等公用库函数,还有非常多的其他库函数以及他们所需的辅助数据结构。在Linux中一个普通的c程序需要的静态库至少1MB以上。

简而言之就是,相同的目标模块每一个程序都会保留一份obj文件。

  更新困难:一旦程序中有任何模块更新,整个程序都需要重新连接,发布给用户。

动态链接

  一种简单办法就是把程序的模块互相分割开来,形成独立的文件,而不再把它们静态地链接在一起。就是不对那些组成程序的目标文件进行链接等到程序要运行时才进行链接。把链接这个过程推迟到运行时在进行,这就是动态链接。


当我们运行Program1这个程序时,系统先加载Program1.o文件,当系统发现Program1.o中用到了Lib.o(Pro.o 依赖于 Lib.o),那么系统接着加载Lib.o,这样将所有以来文件加载至内存。如果所有需要的目标文件加载完毕,如果依赖关系满足,即所有依赖的目标文件目标文件都存在?磁盘,系统开始进行连接工作。这个链接和静态链接非常相似,包括符号解析、地址重定位等。完成这些步骤之后,系统开始把控制权交给Program1.o的程序入口处程序开始运行。这时如果我们需要运行Program2,那么系统只需要加载Program2.o,而不需要重新加载Lib。o因为在内存中已经存在了一份Lib.o副本,系统需要做的只是将Program2.o和lib.o链接起来。 

优点:节省空间;模块化更新;提高程序的可扩展性和兼容性:在运行时可以动态的选择加载各种程序模块(开发插件)/ 一个程序在不同的平台运行时可以动态地连接到由操作系统提供的动态链接库。

缺点:当程序所依赖的某个模块更新后,由于新的模块与旧的模块之间接口不兼容,导致原有的程序无法运行。“DLL Hell”//  链接速度:慢一些

实现:

  使用obj目标文件来进行动态链接是理论可行的。但是实际上两者之间还是有些区别的。

  在Linux动态链接文件被称为动态共享对象DSO,dynamic shared objects. 通常就是我们常见的.dll为扩展名的文件。Linux 下C语言常用的运行库glibc以动态连接形式的版本保存在/lib目录下,文件名叫:libc.so:整个系统只有一份C语言的动态链接库。所有C语言编写的动态链接的程序都可以使用它。当程序装载的时候。

  例子:我们有三个源代码文件:Program1.c、Program2.c、Lib.h

  使用GCC将lib.c翻译成一个共享对象文件:

gcc -fPIC -shared -o Lib.so Lib.c

  -shared:标识产生共享对象

  -fPIC:

 

程序员的自我修养-链接、装载与库-7 动态链接