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

通俗举例讲解动态链接】静态链接

参考动态链接 - 知乎

加上我自己的理解,比较好懂,但可能在细节方面有偏差,但总体是一致的

静态链接的背景

静态链接使得不同的程序开发者和部门能够相对独立的开发和测试自己的程序模块,从某种意义上来讲大大促进了程序开发的效率,原先现在程序规模也随之扩大。
但静态链接的缺点也暴露出来:浪费内存、磁盘空间、模块更新困难(耦合性太强)。

内存与磁盘空间

静态链接在计算机早期还是比较流行的,但是到了后面,其缺点也非常明显。比如浪费内存和磁盘空间,更新模块困难等。

一个文件的转换进程

hello.c(源程序[文本])->预处理器(cpp)->hello.i(修改了的源程序[文本])->编译器(ccl)->hello.s(汇编程序[文本])->汇编器(as)->hello.o(可重定位目标程序[二进制])->链接器(ld)->hello(可执行目标程序[二进制])

只需要注意:

hello.c:源文件

hello.o:由hello.c编译而来

hello(可执行目标程序[二进制]),最终执行文件。

比如我有a.cpp ,a.h,b.cpp c.cpp四个文件

a.cpp 定义了一个函数sayHello

#include <iostream>
void sayHello(){std::cout<<"hello world!";
}

a.h

#ifndef UNTITLED1_A_H
#define UNTITLED1_A_Hvoid sayHello();#endif //UNTITLED1_A_H

b.cpp 调用了a的函数sayHello

#include "a.h"
int main(){sayHello();
}

c.cpp 调用了a的函数sayHello

#include "a.h"
int main(){sayHello();
}

静态链接

如果运行b那么就会结合b.o,以及其调用的a.o生成可执行文件。c运行会另外调用 c.o,a.o生成可执行文件,此时可执行文件可以认为长这样

#include <iostream>
void sayHello(){std::cout<<"hello world!";
}
int main(){sayHello();
}

此时a.o重复了两次,但这两个a.o保存了相同的内容,浪费内存和磁盘。

再比如Program1 & Program2分别包含Program1.o和Program2.o两个模块,并且还共用了Lib.o这个模块。静态链接下,P1和P2都用到了Lib.o这模块,所以它们同时在链接输出的可执行文件P1和P2有两个副本,当同时运行两个程序,Lib.o在磁盘和内存中都有两个副本,浪费空间。

程序开发与发布

静态链接另一个问题是对程序的更新,部署和发布也会很麻烦,我如果在a中更新了sayHello,那么生成的b,c可执行文件里的sayHello还是老的,需要重新连接,很麻烦耦合度很高。

程序有任何模块更新,整个程序就要重新链接,发布给用户,

动态链接

dll文件和so文件

dll文件和so文件都是动态链接库,也叫共享对象文件

动态链接原理

动态链接库就是将程序模块相互独立的分隔开来,形成独立的文件,不再将它们静态地链接到一起。简单而言就是对那些组成程序目标文件的链接,等到程序运行时才进行链接,也就是把链接的过程推迟到运行时才进行,这就是动态链接的基本思想

动态链接没有提前链接的过程,但一般文件都是动态和静态链接结合使用,也有生成可执行文件这一步。

比如我编译a.cpp为共享对象文件a.so,还有a.h

b.cpp为c.o,此时我运行生成可执行文件,生成时侦测到sayHello为动态链接的实现,所以就不执行链接(如果侦测到为静态文件,那么就还是老样子进行链接)

b可执行文件执行时,遇到sayHello,就去动态库so中找这个函数的实现位置,这个找的位置有几类,我们经常用的是一个环境变量,叫LD_LABRARY_PATH,假设这里找到了,找到之后就将a.so加载到内存,链接,进行执行。

c执行时再用到a.so,此时a.so以及被加载到了内存中,所以不用再重新加载了,直接链接就能使用了。

那也就说明了动态链接的其他特点:

动态运行b.cpp之前必须要有a.so和a.h才能运行,所需的动态库本地必须齐全。

动态链接库的存储位置以及名称

lib文件的名称,要和头文件相呼应,不然怎么找对应的lib呢。

 比如

cudnn.h对应libcudnn.so

cudnn_adv_infer.h对应libcudnn_adv_infer.so等等

每一个头文件都要有唯一的一个对应的so文件。

一般so文件会存在lib下,头文件存在include下

如cuda11.6

 

 可以看到

再比如我们c++原生的一些实现

头文件也是在include下,可以看到我们的老熟人头文件iostream等等

 

模块

静态链接中,整个程序最终只有一个可执行文件,它是一个不可以分割的整体,但是在动态链接下,一个程序被分成了若干个文件,有程序的主要部分,即可执行文件(Program1)和
程序所依赖的共享对象(Lib.so),很多时候把这些部分叫做模块,即动态链接下的可执行文件和共享对象都可以看做是程序的一个模块

当程序模块Program1.c被编译成Program1.o时,编译器还不不知道foobar函数的地址,当链接器将Program1.o链接成可执行文件时,这时候链接器必须确定Program1.o中所引用的foobar函数的性质。

  • 如果foobar是一个定义与其它静态目标模块中函数,那么链接器将会按照静态链接的规则,将Program1.o中的foobar地址引用重定位
  • 如果foobar是一个定义在某个动态共享对象中的函数,那么链接器就会将这个符号的引用标记为一个动态链接的符号,不对它进行地址重定位,把这个过程留到装载时再进行

程序如何找到用到的动态库以及查看用到的动态库

动态库的搜索顺序如下:

  • LD_PRELOAD环境变量指定库路径
  • -rpath链接时指定路径
  • LD_LIBRARY_PATH环境变量设置路径
  • /etc/ld.so.conf配置文件指定路径
  • 默认共享库路径,/usr/lib,lib

应该就是按顺序一个一个寻找,直到找到满足要求的实现的动态库为止。

程序是如何找到动态库的? | 守望的个人博客

相关文章:

通俗举例讲解动态链接】静态链接

参考动态链接 - 知乎 加上我自己的理解&#xff0c;比较好懂&#xff0c;但可能在细节方面有偏差,但总体是一致的 静态链接的背景 静态链接使得不同的程序开发者和部门能够相对独立的开发和测试自己的程序模块&#xff0c;从某种意义上来讲大大促进了程序开发的效率&#xf…...

K8S部署常见问题归纳

目录一. 常用错误发现手段二、错误问题1. token 过期2. 时间同步问题3. docker Cgroup Driver 不是systemd4. Failed to create cgroup(未验证&#xff09;子节点误执行kubeadm reset一. 常用错误发现手段 我们在部署经常看到的提示是&#xff1a; [kubelet-check] It seems …...

Redis高可用

最近离职后还没开始找工作&#xff0c;在找工作前去学习一下Redis高可用方案。 目录Redis高可用高可用的概念实现方式持久化主从复制简单结构优化结构优缺点哨兵模式&#xff08;Sentinel&#xff09;哨兵进程的作用自动故障迁移(Automatic failover)优缺点集群优缺点Redis高可…...

Hyperledger Fabric 2.2版本环境搭建

前言 部署环境: CentOS7.9 提前安装好以下工具 git客户端golangdockerdocker-composecurl工具 以下是个人使用的版本 git: 2.39.2golang: 1.18.6docker: 23.0.3dockkekr-compose: v2.17.2curl: 7.29.0 官方文档参考链接&#xff1a;跳转链接&#xff0c;不同的版本对应的官…...

macOS Monterey 12.6.5 (21G531) Boot ISO 原版可引导镜像

本站下载的 macOS 软件包&#xff0c;既可以拖拽到 Applications&#xff08;应用程序&#xff09;下直接安装&#xff0c;也可以制作启动 U 盘安装&#xff0c;或者在虚拟机中启动安装。另外也支持在 Windows 和 Linux 中创建可引导介质。 2023 年 4 月 10 日&#xff08;北京…...

【软件设计师13】数据库设计

数据库设计 1. 数据库设计过程 2. E-R模型 3. E-R图向关系模型的转换 例如一对一联系&#xff0c;可以将联系单独做为关系模式&#xff0c;也可以存放到任意一个实体中 而一对多要合并只能合并到多这边&#xff0c;不能存放到1 多对多则联系必须单独转成一个关系模式 4. 案…...

SpringMVC的全注解开发

文章目录一、spring-mvc.xml 中组件转化为注解形式二、DispatcherServlet加载核心配置类三、消除web.xml一、spring-mvc.xml 中组件转化为注解形式 跟之前全注解开发思路一致&#xff0c; xml配置文件使用核心配置类替代&#xff0c;xml中的标签使用对应的注解替代 <!-- 组件…...

C# | 导出DataGridView中的数据到Excel、CSV、TXT

C# | 导出DataGridView中的数据到Excel、CSV、TXT 文章目录C# | 导出DataGridView中的数据到Excel、CSV、TXT前言DataGridView数据转存DataTableDataTable转Excel方法一、使用Microsoft.Office.Interop.Excel方法二、使用EPPlus库方法三、使用NPOI库DataTable转CSVDataTable转T…...

新规拉开中国生成式AI“百团大战”序幕?

AI将走向何方&#xff1f; ChatGPT在全球范围掀起的AI热潮正在引发越来越多的讨论&#xff0c;AI该如何管理&#xff1f;AI该如何发展&#xff1f;一系列问题都成为人们热议的焦点。此前&#xff0c;马斯克等海外名人就在网络上呼吁OpenAI暂停ChatGPT的模型训练和迭代&#xf…...

日撸 Java 三百行day31

文章目录day31 整数矩阵及其运算面向对象思想java异常处理java中的getter和setter方法代码day31 整数矩阵及其运算 面向对象思想 结合之前day7和day8面向过程开发&#xff0c;只关注了矩阵加法和矩阵乘法的功能。而day31是面向对象开发&#xff0c;一个矩阵类&#xff0c;在这…...

在线绘制思维导图

思维导图是一种可视化的思维工具&#xff0c;它可以将放射性思考具体化为可视的图像和图表。 思维导图利用图文并重的技巧&#xff0c;把各级主题的关系用相互隶属与相关的层级图表现出来&#xff0c;把主题关键词与图像、颜色等建立记忆链接。 它运用图像和颜色等多种元素&…...

月薪20k的性能测试必备技能:发现性能瓶颈掌握性能调优

背景 当下云计算、大数据盛行的背景下&#xff0c;大并发和大吞吐量的需求已经是摆在企业面前的问题了&#xff0c;其中网络的性能要求尤为关键&#xff0c;除了软件本身需要考虑到性能方面的要求&#xff0c;一些硬件上面的优化也是必不可少的。 作为一名测试工作者&#xf…...

3、Web前端学习规划:CSS - 学习规划系列文章

CSS作为Web前端开发的第2种重要的语言&#xff0c;笔者建议在学了HTML之后进行。CSS主要是对于HTML做一个渲染&#xff0c;其也带了一些语言语法函数&#xff0c;功能也非常强大。 1、 简介&#xff1b; CSS(层叠样式表)是一种用于描述网页样式的语言。它可以控制网页中的字体、…...

城市轨道交通列车时刻表优化问题【最优题解】

文章目录城市轨道交通列车时刻表优化问题思路文章底部城市轨道交通列车时刻表优化问题 最新进度在文章最下方卡片&#xff0c;加入获取思路数据代码论文&#xff1a;2023十三届MathorCup交流 (第一时间在CSDN分享&#xff0c;文章底部) 题目为数据分析类题目。列车时刻表优化…...

常年不卷,按时下班,工作能力强,同事求助知无不言,不扯皮,不拉帮结派,这样的职场清流竟然被裁掉了!...

在职场上&#xff0c;你永远想不到什么样的员工会被优化&#xff0c;比如下面这位&#xff1a;常年不卷&#xff0c;按时下班&#xff0c;工作很专业&#xff0c;同事问什么都回答&#xff0c;不扯皮&#xff0c;不拉帮结派&#xff0c;简直是职场清流。在上个月竟然被优化了&a…...

基于改进多目标灰狼优化算法的考虑V2G技术的风、光、荷、储微网多目标日前优化调度研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

Python 函数、文件与模块

“探索 Python” 这一系列的前几篇文章已为 Python 编程新手介绍了几方面的主题&#xff0c;包括变量、容器对象和复合语句。本文以这些概念为基础&#xff0c;构造一个完整的 Python 程序。引入了 Python 函数和模块&#xff0c;并展示了构建一个 Python 程序、将其存储在文件…...

在Spring Boot微服务使用RedisTemplate操作Redis

记录&#xff1a;400 场景&#xff1a;在Spring Boot微服务使用RedisTemplate操作Redis缓存和队列。 使用ValueOperations操作Redis String字符串&#xff1b;使用ListOperations操作Redis List列表&#xff0c;使用HashOperations操作Redis Hash哈希散列&#xff0c;使用SetO…...

4月软件测试面试太难,吃透这份软件测试面试笔记后,成功跳槽涨薪30K

4 月开始&#xff0c;生活工作渐渐步入正轨&#xff0c;但金三银四却没有往年顺利。昨天跟一位高级架构师的前辈聊天时&#xff0c;聊到今年的面试。有两个感受&#xff0c;一个是今年面邀的次数比往年要低不少&#xff0c;再一个就是很多面试者准备明显不足。不少候选人能力其…...

人人拥有ChatGPT的时代来临了,这次微软很大方!

技术迭代的在一段时间内是均匀发展甚至止步不前的&#xff0c;但在某段时间内会指数级别的爆发。 ChatGPT背后的GPT 3.5训练据说花了几百万美金外加几个月的时间&#xff0c;参数大概有1700多亿。 这对于绝大多数的个人或企业来说绝对是太过昂贵的。 然而&#xff0c;微软&am…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...