静态链接库和动态链接库

前言:记得以前看过一点静态链接库和动态链接库的东西,今天想去再看一下,搜了好几篇文章看了下,内容大都有错,所以决定自己写一篇关于静态链接库和动态链接库的东西。有的可以在深入理解计算机系统上可以找到。

 

在讲这篇文章的问题之前,首先简单介绍一下编译的四个阶段。

1.预处理

在预处理阶段编译器只是把头文件展开,并在使用宏定义的地方用原来的东西替换。如下所示

                                                                                               1.替换前

                                                                                                 2.替换后

可以看到2与1相比,把TEST替换成5了,并且把头文件给展开了。(可以用gcc -E main.i main.c编译查看,-E代表只是做预处理)

2.编译

编译阶段做的事就是把你写的代码翻译成汇编(gcc下可以指定-S来实现,如gcc -S main.s main.i)

3.汇编

在汇编阶段做的事就是把上面生成的汇编代码生成可重定位目标文件(二进制文件)。这里大概说一下什么叫可重定位目标文件,可重定位目标文件不能直接运行,第一因为它可能引用了在别的文件定义的函数变量等,第二可重定位还没有决定程序的运行地址。由可重定位目标文件转换成可执行的目标文件要进行两件事:1.符号解析,2.重定位。关于可重定位目标文件就介绍到这里,想要去了解的可以看下深入理解计算机系统的链接那一章。(可以指定-C选项告诉编译器生成可重定位目标文件)。下图是上面实例的可重定位目标文件。

4.链接

链接阶段做的就是把一系列可重定位目标文件组合成一个可执行目标文件,它要做的事情就是上面提到的两个(符号解析和重定位)。这一步生成的也是二进制文件,不过这个二进制文件和汇编阶段生成的不一样,它是可以直接运行的。

关于静态链接库是在链接阶段用到的。

 

静态链接库:

让我们先想一下如果不用静态链接库,我们怎么来链接两个文件呢。

1.我们可以直接把所有的函数封装在一个文件里面,然后生成一个可重定位目标文件,要使用这些函数的就要和这个可重定位目标文件进行链接。但是这样有个不好的地方就是生成的可执行目标文件中会包含所有的函数拷贝进来,不管是用还是没用到的,这样很浪费空间。

2.我们可以为每个标准函数创建一个独立的可重定位目标文件,然而这样的话就需要显示的去链接每个文件。

3.使用静态库文件。把一些系列用途相同的函数封装在一个静态库文件里面,在链接阶段只会拷贝被程序引用的模块(我看好多博客上都写这里会拷贝所有用和没用到的模块,我在深入理解计算机系统中核查了一下,这种说话不对,有疑问的可以去看下这本书的链接那一章),这样就解决了上面提到的两个问题。

 

 

动态链接库:

我们知道使用静态链接库生成的可执行文件会很大,并且当库函数改变的时候需要重新链接。很不方便,动态链接库解决了这个问题。动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。动态库在程序运行是才被载入,也解决了静态库对程序的更新、部署和发布带来麻烦。用户只需要更新动态库即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值