程序员的自我修养第七章——动态链接

news2024/11/26 10:48:36

       继续更新《程序员的自我修养》这个系列,主要是夏天没把它看完,补上遗憾。本篇来自书中第七章。

        再说动态链接前,我们先阐明为什么要动态链接:

        动态链接的产生来自静态链接的局限性。随着静态链接的发展,其限制也越来越大,如浪费空间、模块更新困难等问题暴露了出来。使得人们不得不寻找其他方法,动态链接应运而生。

目录

7.1 动态链接基本介绍

7.2 简单的动态链接

7.3 地址无关代码

未完待续


7.1 动态链接基本介绍

        如上图,静态链接中,progran1和program2都用到了Lib.o,他们分别将Lib.o加到代码内容里并在运行时内存中有两份Lib.o分别来自这两个程序。

        对于程序的开发和发布,静态链接有两个缺点:1. 如果Lib.o来自其他开发团队,他们更新了其中的bug并修改重新发版了,我们作为使用方必须跟进发版,如果我们使用到类似Lib.o的其他lib呢,是不是每个lib发版我们都跟进呢?2. 如果我们使用到了20个公共库里的lib,静态链接将其都装在起来就是20M,这还不算我们自己开发的内容。

动态链接简介:

        动态链接的思想是将程序分割开来,以上图为例:系统将program1装载到内存中,发现它依赖Lib.o,于是将Lib.o也装进去,如果还有什么别的依赖通通装载进去,这个过程和静态链接一样。不同的地方在将program2装载进去后,系统发现内存里已经有了一份Lib.so,那么程序只需将program2和内存里的Lib.o链接起来就好了。

对于程序的拓展性与兼容性来讲。动态链接思想就是插件思想,只有在使用时才装载到内存,可以使用插件思想做程序拓展。动态链接还加强程序的兼容性,如A操作系统和B操作系统对于printf的实现不同,只需操作系统A和B都能提供一个printf的动态链接库。

动态链接在操作系统的实际实现上更为复杂,主流操作系统都支持动态链接,在Linux中被称为动态共享对象(dynamic shared objects),一般以.so为结尾。windows中叫动态链接库(dynamic linking library),文件名以.dll结尾。本质上讲执行程序和动态链接程序本质上都是指令和数据,我们尽可以将其看作他们为平等的程序模块。

linux系统中C语言运行库为glibc,他的动态链接库在/lib下,名字为libc.so,当程序被装载时,系统的动态链接器会将程序所需要的动态链接库装载到地址空间,并将所有未决议的符号绑定到动态链接库中,最后进行重定位工作。这块可以理解为将运行程序中没有找到实现的部分去动态链接库里找,如果没找到,外部链接报错,在visual stadio中很常见了。

我们都知道不可能三角,在程序中也同样成立,动态链接也不是一味的好。首先,早期的动态链接由于协议不全、规范不统一导致互相不兼容。其次,动态链接相比静态链接,链接过程在程序装载的时候,程序每次装载前都要重新链接,对程序运行效率有影响。

7.2 简单的动态链接

简单的例子四段代码:program1.c、program2.c、lib.h、lib.c.

使用命令gcc -fPIC -shared -o Lib.so Lib.c生成Lib.so

再编译program1和program2:

gcc -o program1 program1.c ./Lib.so

gcc -o program2 program2.c ./Lib.so


过程图:

        链接器在符号链接时找到foobar。

        对比静态链接的虚拟地址映射到物理地址,动态链接更复杂。静态链接只将一个文件整体映射到物理内存中。

为了方便查看地址空间,修改代码:

        查看虚拟地址空间分布:

        用readIf来查看Lib.so的装载属性和普通执行文件没区别,但是它地址是从0x00000000开始的,实际不是从这,这意味着动态链接地址在编译时不确定,在装载时根据当前空间去分配。

7.3 地址无关代码

        装载时重定位。

     我们在静态链接时提到过链接重定位(link time relocation),现在为装载重定位(load time relocation),在windows 这种装载时重定位又叫做基址重制(Rebasing),linux的GCC支持这种装载时重制的方法,使用-shared那么输出对象就是使用装载时重定位方法。

        地址无关代码

       

 

        汇编分析:

  1. 模块内部调用跳转:

未完待续

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/177894.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

zookeeper可视化工具

参考资料: 参考网址 使用过程: 首先打开网址,将资源克隆下来解压压缩包 打开压缩目录下 startup.bat ,填入对应地ip即可(记得优先启动zookeeper,否则会报错)

我的1周年创作纪念日

机缘 我目前还是一名六年级小学生,下半年便升入初中了。 我是在2021年上半年(我四年级下期时)开始学习C的。后来我自己想做一些小游戏,便经常要在百度上搜索,后来就发现CSDN中的内容比较全面,便加入了CSD…

MacOS下在Pycharm中配置Pyqt5工具(2023年新版教程)

前提:使用Anaconda的包管理工具进行管理。创建environment,然后在该Environment上进行下载操作!!!一、安装相关模块安装pyqt5、pyqt5-tools两个基础包,命令如下:pip install -i https://pypi.tu…

CSS文本与字体(文本格式化/对齐/装饰/转换/间距/阴影/字体/样式/大小/简写属性)

目录 文本颜色 文本颜色和背景色 文本对齐 文本方向 垂直对齐 文字装饰 文本转换 文字缩进 字母间距 行高 字间距 空白 文本阴影 所有 CSS 文本属性 字体选择很重要 通用字体族 Serif 和 Sans-serif 字体之间的区别 一些字体的例子 CSS font-family 属性 字…

vue-countTo不兼容vue3解决方案

我们想要做一个数值增长的过度效果可以使用vue-count-to 官网的地址:https://www.npmjs.com/package/vue-count-to 官网的截图 vue2的使用方式 cnpm install -S vue-count-to在main.js import vueCountTo from "vue-count-to"; Vue.component("C…

【JavaEE】如何开始基础的Servlet编程(基于Tomcat服务器)

如何开始最简单的Servlet编程?(基于Tomcat服务器)知道了如何借助Tomcat开始进行最简单的Servlet编程后,我们就可以进一步完善功能制作一个基础的网站了。在此之前我们先了解一下Servlet的生命周期。Servlet的生命周期初始化init -…

C++ list

目录 一. 初步了解 1.构造、析构、赋值 2.容量 3.元素访问 4.增删 二. 模拟实现 框架 push_back 迭代器 带参构造、析构、赋值 增删 反向迭代器 所有代码 说白了,就是一个双向循环带头链表,由于我们在数据结构中已经学习过链表的知识&a…

macOS Big Sur 11.7.3 (20G1116) Boot ISO 原版可引导镜像

本站下载的 macOS Big Sur 软件包,既可以拖拽到 Applications(应用程序)下直接安装,也可以制作启动 U 盘安装,或者在虚拟机中启动安装。 请访问原文链接:https://sysin.org/blog/macOS-Big-Sur-boot-iso/&a…

Nginx学习整理|入门记录

目录 1. Nginx概述 1.1 Nginx介绍 1.2 Nginx下载和安装 1.3 Nginx目录结构 2. Nginx命令 3. Nginx配置文件结构 4. Nginx具体应用 4.1 部署静态资源 4.2 反向代理 4.3 负载均衡 1. Nginx概述 1.1 Nginx介绍 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件…

积分电路的并联电阻、反向放大电路的并联电容的区别?

运放反相比例放大电路中反馈电阻两端经常并联一个电容,而运放积分电路的反馈电容上常常并联一个电阻,两者电路结构相似,如下所示(隐去阻容值),二者有何区别呢?电阻、电容分别又起到什么作用&…

Catboost

CatBoost简介 CatBoost是俄罗斯搜索巨头Yandex在2017年开源的机器学习库,是Boosting算法的一种,CatBoost和XGBoost,Lightgbm并称为GBDT三大主流神器,都是在GBDT算法框架下的一种改进实现,XGBoost是被广泛应用于工业界…

使用jstack解决线程爆满问题

问题发现生产应用现存在问题,影响到系统的使用,前端页面只配置了35个派生指标,后台任务生成20000多线程任务,占用了全部资源,导致其他系统也没资源可用,指标工厂也无法进一步使用,今天上午发的死…

Email Signature Manager 9.3 Crack

概述 Email Signature Manager为所有用户创建和部署电子邮件签名 包括合并的联系方式、公司徽标、社交媒体图标 和链接,甚至个性化内容,如用户照片 创建和附加电子邮件活动,向所有人介绍奖项, 活动或促销,或设置运行的…

基于STM32的FreeRTOS开发(1)----FreeRTOS简介

为什么使用freertos FreeRTOS 是一个免费和开源的实时操作系统,它主要用于嵌入式系统。它非常轻量级,可以在很小的硬件资源上运行,因此非常适合在限制硬件资源的嵌入式系统中使用。 FreeRTOS提供了一组简单的任务管理功能,可以让…

基于Springboot vue前后端分离在线培训考试系统源码

# 云帆培训考试系统 管理账号:admin/admin 学员账号:person/person # 介绍 一款多角色在线培训考试系统,系统集成了用户管理、角色管理、部门管理、题库管理、试题管理、试题导入导出、考试管理、在线考试、错题训练等功能,考…

C++:运算符重载与类的赋值运算符重载函数

目录 章节知识架构 一.运算符重载 1. 运算符重载的基本概念 代码段1 2.关于运算符重载的重要语法细则 二.运算符重载在类中的使用 三.类的默认成员函数:重载函数(赋值运算符重载) 1.自定义重载函数 代码段2 2.编译器默认生成的重载函数 四.前置(--)和后置…

Facebook小组与主页:哪个更适合SEO?

在 SEO中,对于优化人员来说有两种策略:一种是在 Facebook组上投放广告;另一种则是在主页上投放广告。那么,这两种策略哪种更好呢?对于 SEO来说又有什么影响呢?如果你已经在 Facebook上进行了一些优化工作&a…

Python---文件操作

专栏:python 个人主页:HaiFan. 专栏简介:本专栏主要更新一些python的基础知识,也会实现一些小游戏和通讯录,学时管理系统之类的,有兴趣的朋友可以关注一下。 文件操作思维导图前言文件是什么文件路径文件操…

SpringBoot基础回顾:场景启动器

上一章我们回顾了 SpringBoot 的自动装配,以及承载自动装配的核心——自动配置类。自动配置类的定义位置通常在每个场景的 jar 包中,配置 spring.factories 文件中 EnableAutoConfiguration 的位置通常在相应的 autoconfigure jar 包下。本章会着重回顾和…

SpringMVC简介

SpringMVC简介什么是MVC?MVC的工作流程什么是SpringMVC?HelloWorld创建maven工程配置web.xml创建请求控制器配置springMVC.xml配置文件什么是MVC? MVC是一种软件架构的思想,将软件按照模型、视图、控制器来划分 M:Model,模型层,指工程中的javaBean,作用是是处理数…