当前位置: 首页 > news >正文

Linux:动态链接与静态链接以及动态库与静态库

引言:

我准备用三个月聚焦Linux学习,从系统编译到网络编译,让我们对Linux有全新的认识

前一章博客的问题这一章就会得到解答,所以接下来的博客就敬请期待

动态链接和静态链接


静态链接:

在我们的实际开发中,不可能将所有代码放在⼀个源⽂件中,所以会出现多个源⽂件,⽽且多个源⽂件之间不是独⽴的,⽽会存在多种依赖关系,如⼀个源⽂件可能要调⽤另⼀个源⽂件中定义的函数,但是每个源⽂件都是独⽴编译的,即每个*.c⽂件会形成⼀个*.o⽂件,为了满⾜前⾯说的依赖关系,则需要将这些源⽂件产⽣的⽬标⽂件进⾏链接,从⽽形成⼀个可以执⾏的程序。这个链接的过程就是静态链接。
静态链接的缺点很明显:
• 浪费空间:因为每个可执⾏程序中对所有需要的⽬标⽂件都要有⼀份副本,所以如果多个程序对
同⼀个⽬标⽂件都有依赖,如多个程序中都调⽤了printf()函数,则这多个程序中都含有
printf.o,所以同⼀个⽬标⽂件都在内存存在多个副本;
• 更新⽐较困难:因为每当库函数的代码修改了,这个时候就需要重新进⾏编译链接形成可执⾏程
序。
静态链接的优点:
在可执⾏程序中已经具备了所有执⾏程序所需要的任何东西,在执⾏的时候运⾏速度快


动态链接:


动态链接的出现解决了静态链接中提到问题。动态链接的基本思想是把程序按照模块拆分成各个相对独⽴部分,在程序运⾏时才将它们链接在⼀起形成⼀个完整的程序,⽽不是像静态链接⼀样把所有程序模块都链接成⼀个单独的可执⾏⽂件。
动态链接其实远⽐静态链接要常⽤得多。⽐如我们查看下 code 这个可执⾏程序依赖的动态库,会发现它就⽤到了⼀个stdc++动态链接库:

一般我们看名字是将前面的lib和后面的.*去掉

在这⾥涉及到⼀个重要的概念: 库


• 我们的cpp程序中,并没有定义“cout”的函数实现,且在预编译中包含的“iostream”中也只有该
函数的声明,⽽没有定义函数的实现,那么,是在哪⾥实“cout”函数的呢?
• 最后的答案是:系统把这些函数实现都被做到名为 libstdc++.so.6 的库⽂件中去了,在没有特别指定
时,gcc 会到系统默认的搜索路径“/usr/lib”下进⾏查找,也就是链接到 libstdc++.so.6 库函数中去,这样
就能实现函数“cout”了,⽽这也就是链接的作⽤

静态库和动态库


• 静态库是指编译链接时,把库⽂件的代码全部加⼊到可执⾏⽂件中,因此⽣成的⽂件⽐较⼤,但在运
⾏时也就不再需要库⽂件了。其后缀名⼀般为“.a”
• 动态库与之相反,在编译链接时并没有把库⽂件的代码加⼊到可执⾏⽂件中,⽽是在程序执⾏时由
运⾏时链接⽂件加载库,这样可以节省系统的开销。动态库⼀般后缀名为“.so”,如前⾯所述的
libstdc++.so.6 就是动态库。g++ 在编译时默认使⽤动态库。完成了链接之后,g++ 就可以⽣成可执⾏⽂件,如下所⽰
• gcc默认⽣成的⼆进制程序,是动态链接的,这点可以通过 file 命令验证(file后面会简绍)
📌 注意1:
• Linux下,动态库XXX.so, 静态库XXX.a
• Windows下,动态库XXX.dll, 静态库XXX.lib
📌 注意2:
⼀般我们的云服务器,C/C++的静态库并没有安装,可以采⽤如下⽅法安装

安装完成后,可以来看看动态链接和静态链接的内存大小

高了百倍,因为静态链接就是拷贝了一份需要的库,而动态链接只需要记录动态库的地址,到时候去查找就行

用file可以查看这个可执行程序是什么链接方式

对比维度静态库(.a)动态库(.so)
编译阶段编译时直接嵌入可执行文件编译时仅记录库地址,运行时加载
文件大小较大(包含库代码副本)较小(仅存链接信息)
运行依赖不依赖系统库,可独立运行依赖系统存在对应动态库
运行速度更快(无需加载外部库)稍慢(运行时动态加载)
更新维护库更新需重新编译程序库更新无需重新编译程序
内存占用多个程序共用库时,内存多副本多个程序共用库时,内存单副本

其他问题:


• 条件编译应⽤场景

分割代码,比如你买一个编译器,有专业版有免费版,免费版就是把专业版的功能剪切下来的,为了实现这个功能,有两种办法,一种就是写很多个不同的代码对应不同的情况,但是维护起来十分麻烦,因为有很多份代码,更新也麻烦,也徒增工作量,也有一种方法是条件编译,既可以只使用一份代码使用条件编辑剪切不同份,维护成本更新成本都相对很低

• 为什么⾮得把语⾔变成汇编

这是因为历史问题,最先出现有编译器的是汇编语言,汇编语言编译器会将汇编语言转化为二进制语言让计算机做出指令,既然有了这个编译器,那以后的语言只需要将自己的语言编译为汇编语言就可以了,降本增效,我们无需成为巨人,我们可以站在巨人的肩膀上


• 编译器⾃举

用你发明的语言写的编译器在汇编编译器上跑一下,生成出的新的文件就是你的编译器汇编代码,这样相当于你发明的语言在用你语言写的编译器上汇编为汇编语言,实现功能完成闭环,这就是自举

http://www.dtcms.com/a/611695.html

相关文章:

  • 如何来构建一个成交型网站企业品牌vi设计
  • 深圳网站建设快速排名自适应网站可以做伪静态页面吗
  • 学网站建设的工资高吗软件网站关键词优化
  • 代理记账 营销型网站沈阳seo博客
  • 有谁用2008做网站服务器施工企业会计王玉红课后答案
  • 【教学类-98-04】20251114《动物花花衣》只有轮廓的动物
  • 获取网站访客qq 原理wordpress mysql 5.7
  • C语言--结构体(Struct)
  • 网站建设忄金手指专业简单aspx网站开发
  • wordpress 导航网站模板设计新颖的网站建站
  • 一起做网店一样的网站北京建设高端网站
  • openEuler 22.03 ARM64 KVM虚拟化安装
  • 西安知名的网站建设公司wordpress登录失败
  • 如何在会议决策错误后进行纠正与说明
  • 哪个网站免费h5模板多网络推广外包注意哪些
  • 网站的布局怎么做采集文章留在网站
  • 淘宝做导航网站织梦网站搬家教程
  • 男人直接做的视频网站注册网站会不会有问题
  • 在那个网站做直播好赚钱吗企业网站seo模板
  • 无锡网站建设开发外贸自建站类型
  • 晋江网站建设联系电话天眼查网站建设公司
  • 什么网站都有漏洞电脑上安装wordpress
  • 宁波网站搭建公司定制企业营销推广
  • ISTJ+RCI_突然的想法-称之为灵感
  • 手机做网站用什么软件吐鲁番高端网站建设平台
  • Java 黑马程序员学习笔记(进阶篇26)
  • 网站开发的进度怎么写网站开发里程碑
  • Xshell终端连接Ubuntu/Debian无颜色的解决方案
  • 国外推广网站有哪些网页设计介绍北京网站
  • 贵港网站建设兼职企业做网站需要什么