注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

编译链接和加载分析之一静态库与动态库的编译处理的不同  

2016-08-02 14:18:29|  分类: C++(VC)编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

编译链接和加载分析之一静态库与动态库的编译处理的不同

 

在看《高级C/C++编译技术》中,第四章“重用概念的作用”的4.2.4节一开始说“创建静态库时并不需要链接操作”。这是什么意思?为什么DLL即动态库需要编译链接(含链接阶段的“重定位”和“解析引用”).

大家都知道,动态库是需要在执行阶段动态加载到程序的内存中去的,通过修改.text或者相关的段来适应动态的加载。换句话说,DLL是必须能够加载上就可运行行,也就是说是基于二进制的片段的嵌入。

那么,这样就明白了,如果DLL的文件一旦加载就能执行,一定是执行好了编译和链接,否则程序不可能在运行的时候儿自动去链接相关的地址。

反过来,静态库呢?Windows上的LIB不太明显,但在LINUX就非常明显了,静态库.a其实就是一系列的.o文件的压缩包。换句话说,.o是中间文件,你也可以简单理解成是源文件(这当然不准确,但是容易理解),程序在使用静态库时,是需要把整个程序链接到自己的程序的,也就是说它会重新链接所有的.o文件。这样,静态库自己就不用再链接了。如果以刚刚不准确的方式理解就是,静态库以源码参与调用程序的链接。不用自己搞定。

书也提到,静态库只是导入符号表,而动态库是需要整个二进制文件的导入。

大家在学习WIN上的动态库和静态库时,会发现一个问题,那就是动态库也有.lib文件,而静态库也是.lib文件。好多初学的人,甚至相当一部分老手都不太明白这有什么区别?

.lib在静态库中,就是静态库,但在在DLL中出现的作用是提供“导出库文件”,说得明白一些就是提供一些导出的符号表之类的东东。这也是为什么在WIN上库比LINUX上复杂的原因。另外,他还提供了一个.exp导出文件,主要是解决可执行文件的循环依赖的问题。

WIN上,所有的库的执行都要在编译阶段确定各种符号的解析,但在LINUX下,一些动态的符号可以在编译阶段略过,在程序运行时动态链接,并在内存映射中找到相应的符号内容。

静态库的历史要比动态库早很多,在汇编时代,静态库就已经存在了。所以动态库的技术其实比静态库要复杂,要后出现。

早期的动态库,一般来说是在应用程序需要加载DLLso)时,才会加载相关库,为了保证进程间的独立性,一般来说,每个进程会维持着一会儿相同的库的副本。这样做的目的是非常明显也非常容易达到我们的目的。但是,在应用的数量级小的时候儿如此,如果应用的数量级增大,就会出现一个问题,相同的二进制的代码片段会有很多相同的加载到了内存中。

于是,就出了PIC(position independent code),LINUX链接选项会是-fPIC,这个如何使用前面总结过几次,这里不赘述。不过特别说明的是,这个选项在32位的机器是是可选的,但是在X64上,是必须要有的,否则在使用编译好的库时,会出现链接错误,这也是在实际工程中遇到后才明白的。

从这里又引申出一个比较容易混淆的概念,就是动态库和共享库,如果是副本引用的,就是动态库,如果是内存映射引用同一个副本的,就是共享库,或者换句话说,在32位上,动态库多,在64位系统上,共享库为主。

4.3.1节中3中提到了中介动态库(The intermediary dynamic library,需要明白;

在《高级C/C++编译技术》中,也提到了在64位的情况下被大量编译器使用。

这里用本书中的一个类比来说明二者的不同,觉得非常形象,做了中国化的一些修改:

静态库是一些超市里卖的半成品菜肴,好看,种类多,但是你得弄回来重新做些处理,最重的是要加热,要炒制。

动态库是一些配菜,举一个例子,大家一般习惯在吃东西的时候弄点甜面酱或者果酱、沙拉以及小菜之类的东西,单独吃这类东西一般来说是没有意义的,但是如果配上肉呀或者其它的食材,就相当棒了。而且这种东西可以应用到非常多的食材上。

可执行程序呢?就是一顿大餐,没有前二者,都可以,但是一般来说,在家庭小作坊里,是比较少见的。可是在大型的餐饮或者宴会上,这两者就是必须的了,一个是为了提高速度保证质量,另外一个就是提供不断的可变化的新的菜品的体验。

  评论这张
 
阅读(72)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017