首页 > 其他分享 >【攻防技术系列】动态库和静态库有什么区别?

【攻防技术系列】动态库和静态库有什么区别?

时间:2024-06-20 17:59:38浏览次数:21  
标签:攻防 静态 代码 可执行程序 编译 库有 动态 链接

计算机的运行当然离不开内存。

程序运行在内存当中,那么程序在内存中的布局是什么样子的呢?

程序的内存分为代码区、数据区、堆区和栈区,它们的布局是这样的,这里重点看代码区。

代码区中是什么呢?

这里主要就是你写的代码,当然还有你使用的库。

这里主要是标准库,以及非标准库,也就是普通的库。

接下来我们来看第一个阶段:编译。

假设你在编写一段空前绝后的代码,需要使用加法函数,考虑到这个函数可能其它人也需要,因此单独放到一个源文件中,其它类似的函数也一样。

接下来是编译过程,先编译成目标文件,链接器把目标文件打包成最终的可执行程序。

由于你实现的加减乘除等函数非常好用,广受其它程序员的欢迎,因此你写的代码渐渐的变成了一种标准,所有程序员都遵循,标准库就是这么诞生的。

当然,你写的代码也可能根本没有其它人用,只能当做你自己使用的普通库,实际上这才是人生常态,这样的非标准库还是留着自己用吧。

不管是标准库还是非标准库对后续的讲解都是一样的,因此我们以标准库为例来讲解。

现在有了标准库,所有人都很开心,终于不用重复造轮子了。

但是很快你会发现,及时写一个最简单的hello world程序,也不得不重新编译一堆标准库代码。

这显然是很浪费时间的,但这对打工人来说是很不错,可以利用编译时间合理摸鱼。

该怎么解决重复编译标准库的问题呢。

很简单,可以提前把标准库编译出来。

这样我们再次编译自己的项目时直接跳过标准库的编译过程,直接把标准库链接到最终的可执行程序中。

接下来我们来到了第二阶段,链接。

链接器从表面看实际上是一个打包器,把各种目标文件,也就是你的代码和标准库打包起来,如果还有其它库也是一样的道理,经过链接会生成最终的可执行程序。

注意看最终的可执行程序中,包含了你的代码和使用的库,这种将所有代码打包到可执行程序的链接方式叫做静态链接。

可执行程序当然是保存在磁盘中的,接下来我们双击运行这个程序。

此时会在内存中划分出一块区域,这里就是我们最开始看到的堆区、栈区、数据和代码区。

这时会把可执行程序中的指令都拷贝到代码区,这就是程序运行的最基本原理。

显然计算机系统里不会只有一个程序。

可能会有很多个,如果所有程序都采用静态链接会怎样呢?

如果都是静态链接,那么这些程序都保存一份标准库,由于是标准库,因此它们的内容都是一样的,最终这些程序都保存在磁盘上,占据磁盘空间:

而在运行起来后同样会占用内存空间。

注意看这里 和这里,它们的内容都是一样的,这显然是在浪费宝贵的存储资源。

问题出在哪里呢?

注意看这里,每个可执行程序都包含有一份标准库。

这就像什么呢?这就像一本非常厚的书,这本书把引用到的所有内容到装订在一起。

好处当然是更方便读者阅读引用到的内容,但问题就是这样的书太厚重了,更好的方法是把引用到内容放在一页参考文献中而不要打包在一起,这样一本书就很轻量了。

可执行程序也是一样的道理,我们不再打包一切而是使用参考文献。

这就是所谓的动态链接。

这时提前编译好的库就是动态库,linux下以.so为结尾,windows中是dll文件。

这时的可执行程序中不再包含完整的动态库代码,而是只有一份参考文献,你可以想象一下,这里肯定保存了两项基本信息,依赖了哪个库,这个库保存在了哪里。

这样及时有再多的可执行程序也不怕,因为我们只需要保存一份标准库。

动态链接的程序该怎么运行呢?依然是把可执行程序拷贝到代码区,然后根据参考文献把动态库加载进来,这时才是真正的链接,也就是所谓的动态链接,我们把链接这个过程从编译期推迟到了运行时。

如果是其它程序运行呢?道理也一样。

动态链接下每个程序中不会有一份标准库,而是大家共享内存中的同一份标准库。

这样利用动态链接我们不但节省了磁盘空间也节省了内存空间。

接下来我们简单总结一下静态库和动态库的区别了。

首先是静态链接。

静态链接下的可执行程序中打包了所以用到的东西,就和这个工具箱一样,这样的程序不再依赖其它库。

因此在大规模部署到服务器时非常方便,所以你会看到一些互联网服务程序很多采用静态链接。

但是静态链接也有自己缺点,那就是修复bug不是很方便,你需要从头开始编译链接生成最终的可执行程序,然后重新部署服务并重启。

同时静态链接也有我们刚提到的重复占据磁盘和内存空间的问题,而动态库则没有这个问题。

当然我们说静态库的这一问题这是站在单机一台机器有多个应用的角度,而对于一个应用需要部署在多机的角度这些都不是事。

接下来我们看动态库。

假设你用动态链接的方式构建了一个非常受欢迎的应用程序,然后发布出去。

发布出去后发现动态库模块有bug,那么该怎么修复呢?很简单,只需要修复bug后重新生成新的动态库,简单的更新动态库即可,而不需要重新发布应用。

这就是为什么很多应用程序采用动态链接的原因。

原创 码农的荒岛求生

标签:攻防,静态,代码,可执行程序,编译,库有,动态,链接
From: https://www.cnblogs.com/o-O-oO/p/18258374

相关文章