程序员的自我修养-链接、装载与库-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:

时间: 2024-10-13 22:50:35

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

读《程序员的自我修养 —— 装载与动态链接》乱摘

2016.05.14 – <程序员的自我修养 -- 链接.装载与库>的装载与动态链接部分. - 余甲子 石凡 潘爱民编 个人选读笔记 - 学点表皮. 05.14 PART II 装载与动态链接 1 可执行文件的装载与进程 1.1 进程虚拟地址空间的大小 每个进程拥有自己独立的虚拟地址空间,该虚拟地址空间的大小由计算机的硬件平台决定,具体地说是由CPU的位数决定的(地址线 -- C语言中的指针所占空间).硬件决定了地址空间的最大理论上限,即硬件的寻址空间大小,如32位的硬件平台决定了虚拟地址空间

程序员的自我修养—链接、装载与库pdf

下载地址:网盘下载 内容简介 编辑 <程序员的自我修养:链接.装载与库>对装载.链接和库进行了深入浅出的剖析,并且辅以大量的例子和图表,可以作为计算机软件专业和其他相关专业大学本科高年级学生深入学习系统软件的参考书.同时,还可作为各行业从事软件开发的工程师.研究人员以及其他对系统软件实现机制和技术感兴趣者的自学教材. 媒体评论 编辑 这是一本深人阐述链接.装载和库等问题的优秀图书,读来让人愉悦,你从巾可以清晰地了解程序的前世今生,彻底理解敲人的代码如何变成程序任系统中运行.通读本书不管对于开发

《程序员的自我修养》 第二章——编译和链接

摘自http://blog.chinaunix.net/uid-26548237-id-3839979.html <程序员的自我修养>第二章——编译和链接 2.1 被隐藏了的过程    C语句的经典,“Hello World”程序几乎是每个程序员闭着眼睛都能写出的,编译运行一气呵成,基本成了程序入门和开发环境测试的默认标准. #include <stdio.h> int main() { printf("Hello World\n"); return 0; 在L

程序员的自我修养:(1)目标文件

程序员的自我修养:(1)目标文件 1.目标文件 1.1 编译与链接 在使用像Visual Studio或Qt Creator等IDE时,通常有一个叫做"构建"的按钮.当编辑完成要运行和测试时点一下它,程序就能跑起来了,所以我们很少关心编译和链接.其实,编译和链接合并在一起就称为 构建(Build).简单的一次按键,实际背后却是异常复杂的过程: 预编译(Preprocessing) 编译(Compilation) 扫描:算法类似有限状态机(FSM),将字符转换成Token. 语法分析:分

读《程序员的自我修养》感受

这书不错,链接-装载-库 我觉得是很底层的东西.比如很多人闭着眼睛都能写出来的hello world(当然不包括brianfuck,如果你会,你真的闹残了吗= =), 其实链接编译器做了很多,不然就哪来的printf,这IO初始化也是CRT(c runtime)库完成的.堆栈的初始化,还有系统装载让程序运行等等.涉及很多. 书里后面就讲了一个CRT库,自己写一个,感觉不错,学了很多.比如malloc,free的实现,话说还是跨平台的.当然库很小,功能不多,不过写这个也可以学学算法.内存的分配,这

《程序员的自我修养》第三章学习笔记

1,  编译器编译源代码生成的文件叫做目标文件. 从结构上说,是编译后的可执行文件,只不过还没有经过链接 3.1 目标文件的格式 1,可执行文件的格式: Windows下的PE  和   Linux下的ELF 2,从广义上说,目标文件与可执行文件的格式几乎是一样的,所以广义上可以将目标文件与可执行文件看成是一种类型的文件. 3,可执行文件,动态链接库,静态链接库都按照可执行文件格式存储(Windows下是 PE-COFF格式,Linux下是ELF格式). 4,Linux下命令: $: file 

一、《程序员的自我修养》笔记-前言

引子:在linux上写了三年多的c了,平时遇到一些编译和链接的问题仍然很是头痛,感觉很无力,好基友推荐<程序员的自我修养>,趁着周末,速速围观. 先记录下作者在书中抛出来的问题 1.为啥程序是从main函数开始执行? 2.PE/ELF文件存的是啥? 3.如何写一个直接跑在未安装os裸机上的程序? 4.目标文件是啥?链接是啥? 5.链接为啥报错? 6.句柄到底是啥? 7.普通c/c++代码如何被编译成牧宝文件及程序在目标文件中如何存储? 8.目标文件如何被链接器链接到一起,并形成可执行文件? 9

程序员的自我修养

本书主要介绍系统软件的运行机制和原理,涉及在Windows和Linux两个系统平台上,一个应用程序在编译.链接和运行时刻所发生的各种事项,包括:代码指令是如何保存的,库文件如何与应用程序代码静态链接,应用程序如何被装载到内存中并开始运行,动态链接如何实现,C/C++运行库的工作原理,以及操作系统提供的系统服务是如何被调用的.每个技术专题都配备了大量图.表和代码实例,力求将复杂的机制以简洁的形式表达出来.本书最后还提供了一个小巧且跨平台的C/C++运行库MiniCRT,综合展示了与运行库相关的各种

读书笔记:程序员的自我修养-----第一章(综述)

题前:30--45天读完,一周至少3篇读书笔记.不能坚持,不再联系,不再找你. 一. hello world 程序引出的问题,看40天后,再回来看看自己的答案,提升多少. Q1:程序为什么要被编译器编译之后才可以运行?   A1 : 系统执行的机器语言,即二进制文件,程序是文本文件需要编译之后,由链接器链接需要的基本库生成二进制文件. Q2: 编译器在把C语言程序转换成可以执行的机器码的过程中作了什么,怎么做的?   A2: 预处理,汇编器生成汇编文件,编译器生成目标文件,链接器链接生成可执行文

程序员的自我修养笔记

1,为什么内存需要分段和分页机制? 早起的计算机中,程序都是直接运行在物理内存上的.这样做有几个问题: 1)地址空间不隔离,计算机的安全性和稳定性没有办法保证,由于所有的程序都可以访问物理内存,恶意的程序可以很容易修改其他程序的内容,达到破坏的目的. 2)内存使用效率低,当前执行的程序(列入进程A)必须被整个装载到内存中执行,如果需要执行另一个程序时,发现内存空间不足,则需要将进程A的数据整体换出到磁盘. 3)程序运行的地址不确定 为了解决上述的三个问题,引入了虚拟地址.分段和分页的概念. 有了