动态链接

静态链接与动态链接 C/C++中的静态链接与动态链接详解。 阅读详情

1.为什么要动态链接

       静态链接有两大缺陷:

①浪费内存和存储空间。

       因为各个可执行文件可能会调用相同的库函数及它们所需要的辅助数据结构。假设有两个目标文件Program1.o和Program2.o,都需要和lib.o进行链接形成可执行文件,当用动态链接的时候内存中只需要存在一份lib.so就可以了。

②模块更新困难。

       因为当可执行文件中的一个模块更新之后,所有的模块要重新链接才可以使用。

 

2.动态链接举例

       以Program1.c与Lib.c的动态链接为例如图,


图中将Lib.so与Program1.o并不是真正的进行静态链接,如果在Program1.o中引用了其他模块中的数据或函数,这里假设为foo()。那么链接器会根据foo()的性质做出决定,如果foo()定义于其他静态模块中,那么直接进行静态链接,如果foo()定义于某个动态共享对象中,那么链接器就会将这个符号的引用标记为一个动态链接的符号,不对它进行地址重定位,把这个过程留到装载时再进行。

       链接器如何知道引用的是一个静态符号还是一个动态符号?此时就要用Lib.so。Lib.so中保存了完整的符号信息,把Lib.so也作为链接的输入文件之一,链接器在解析符号时就可以知道该符号是否是定义在Lib.so中的动态符号。重申一下,这里的Lib.so等名称都是例子中的名称。

 

3.动态链接的装载

①固定装载地址

       固定装载地址对于动态链接来说,效果不好,因为在多个模块被多个程序使用的情况下很复杂,要人为的去安排动态库的装载地址。

②装载时重定位

    静态链接所用到的重定位是链接时重定位,而这里动态链接可以用装载时重定位,当各模块装载至进程虚拟内存中之后,可以对引用到的符号地址进行重定位。

    但是这也带来一个问题,就是动态库中的代码部分所有进程都共享一份,否则就失去了动态链接的意义。当动态链接模块被装载映射至虚拟空间后,由于装载时重定位的方法需要修改指令,所以没有办法做到同一份指令被多个进程共享。

    为什么要修改指令?——见下面地址无关代码的㈢

③地址无关代码(PIC)(Position-independent Code)

    由于装载时重定位的确定,我们希望模块中共享的指令部分在装载时不需要因为装载地址的改变而改变,所以实现的基本想法就是把指令中那些需要修改的部分分离出来,跟数据部分放在一起,这样指令部分就可以保持不变。

    对于共享文件中的地址引用方式可分为4种:

㈠模块内部的函数调用、跳转等

    这种情况下,只要用相对偏移指令就可以了,所以不会改变代码。

㈡模块内部的数据访问,比如模块中定义的全局变量、静态变量

    模块内部的数据访问依然可以用相对寻址(指令中不能包含数据的绝对地址),虽然现代的体系结构中,数据的相对寻址往往没有相对与当前指令(PC)的寻址方式,但是还是有很多方法得到PC值之后加一个偏移进行对数据的寻址的。


㈢模块间数据访问

       因为模块间的数据访问目标地址要等到装载时才能确定。地址无关代码的基本思想就是把跟地址相关的部分放到数据段里面。ELF的做法就是在数据段里面建立一个指向这些变量的指针数组,也被称为全局偏移表(Global Offset Table,GOT),当代码需要引用该全局变量时,可以通过GOT中相对应的项间接引用,基本机制如下图:


㈣模块间调用、跳转

       对于模块间的调用和跳转也可以运用GOT来解决,不同的是GOT中存储的目标函数的地址。


4.延迟绑定(PLT)

       动态链接比静态链接要灵活得多,但它是以牺牲一部分性能为代价的(装载后链接的性能)。在一个程序运行过程中,可能很多函数在程序执行完时都不会被用到,比如一些错误处理函数或用户很少使用到的功能模块等,如果一开始就把所有函数都链接好实际上是一种浪费,所以采用一种叫做延迟绑定(Lazy Binding)的技术,基本思想就是当函数第一次被用到时才进行绑定(符号查找,重定位等)。而这些绑定是由动态链接器来负责的,所以在加载的时候动态链接器是加载到进程虚拟地址空间中的。

       ELF使用PLT(Procedure Linkage Table)来实现,具体就不展开了。



C++_编写动态链接库 动态链接库简介动态链接库(Dynamic Link Library 或者 Dynamic-link Library,缩写为 DLL),是微软公司在微软Windows操作系统中,实现共享函数库概念的一种方式。这些库函数的扩展名是 ”.dll”、”.ocx”(包含ActiveX控制的库)或者 “.drv”(旧式的系统驱动程序)。 动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可 阅读详情

相关推荐

动态链接库的创建和使用

动态链接库的创建和使用 一. 创建动态链接库 1. 创建动态链接库项目 1. 1 动态链接库(DLL) 项目结构如下 为了节约大型项目的编译时间,系统自动为我们生成了和预编译头相关两个文件pch.cpp和pch.h,我们可以选择保留或者是删除他们。如果决定保留则需要在项目中每个源文件的最前面加入#include "pch.h",否则无法通过编译。如果删除了他们,同时还需要到项目属性中禁用预编译头,具体方法如下: dllmain.cpp定义了动态库的入口,当系统开始或终止一个进程或线程的时候,会调用每个

cmiao-me 2813

认识链接器

然后我对这个接口发起了请求,后端服务就需要从如何接受请求,如何再返回,中间出现的问题都需要进行处理,每个接口都这么写,就很烦,所以一门语言创造出来就需要对基础通用的功能进行封装,这里每个语言都需要 HTTP协议 的实现,所以每个语言还需要提供他的库函数。如果一个函数需要调用另一个函数的返回值,但是这个返回值的是个函数内部的一个地址,如果函数被释放,这地址中的值,就是脏数据,如果当前函数去接受这个地址取数据,就有可能取到一些莫名其妙的数据,这个也称为野指针。这些都是公共的接口,不需要重复编写。

FENG_CLOWN的博客 733

运动控制器动态链接库

资料为固高运动控制器动态链接库(dll文件)。在 Windows 系统下,无论是C#,C, C++、Visual Basic 和 Delphi 均可使用。

《链接装载与库》第七章——动态链接

将程序的模块互相分割开,不让它们静态地链接在一起;即不对那些组成程序的目标文件进行链接,等到程序运行时再链接。有如Program1和Program2两个程序,并假定保留了Program1.o、Program2.o和Lib.o三个文件。当我们需要运行Program1这个程序时,系统首先加载 Program1.o,而系统发现Program1.o中用到了Lib.o,即Program1.o依赖于Lib.o,此时系统加载Lib.o,并将其加载至内存。所有需要的目标文件加载完毕后,若依赖关系满足,即所有的依赖文件都在磁

yelvens的博客 6608

深入解析Apollo Lattice Planner:自动驾驶轨迹规划的核心算法与实践

本文深入解析了百度Apollo自动驾驶平台中的核心轨迹规划算法——Lattice Planner。文章详细阐述了其作为车辆“即时决策者”的工作原理,通过“采样-评估”的六步流程(Frenet坐标转换、状态采样、轨迹生成、硬约束过滤、代价函数打分及决策平滑),在复杂路况下实时规划出安全、舒适、高效的行驶轨迹。该算法是自动驾驶实现智能决策与精准控制的关键技术。

weixin_29090677的博客 829

C# Socket网络通信UDP(关键字:Socket)

简单Socket-Udp通信 在本文中涉及到通信,仅做简单的通信(服务端接受消息,由客户端发出消息) 如有需要,根据需求可直接copy使用 关键字Socket 需要引用命名空间: using System.Net; using System.Net.Sockets; 服务端: using System; using System.Net; using System.Net.Sockets; u...

MelanceXin的博客 3884

【C/C++ 库的动态链接】深入理解动态链接器:RPATH, RUNPATH与$ORIGIN

动态链接的过程可以看作是一个解决问题的心理过程。当我们面临一个问题时,我们的大脑会自动寻找已知的解决方案或策略。同样,当程序运行时,动态链接器会自动寻找程序所需的库,并确保它们正确地链接在一起。 1. **加载程序**:当你运行一个程序时,操作系统首先加载程序的可执行文件到内存中。 2. **解析依赖**:动态链接器检查程序的头部,找出程序依赖的所有共享库。 3. **加载共享库**:动态链接器查找这些共享库的位置,并将它们加载到内存中。 4. **符号解析**:动态链接器解析程序中的符号引用,确保它们指

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 1736

YOLOv12涨点改进 | CVPR 2026 |独家创新首发、特征融合改进篇 | 引入Local Attender 局部注意力算子融合模块,高效捕捉小目标和密集目标的局部上下文特征,助力高效涨点

🚀本文提出LocalAttender模块改进YOLOv12模型,通过局部注意力机制解决传统上采样方法的语义漂移问题。该模块采用固定偏移邻域加权聚合方式,在保持线性计算复杂度的同时有效捕捉小目标和密集目标的局部特征。实验表明,LocalAttender能显著提升检测精度而不增加过多计算负担,且与YOLOv12兼容性强。文章详细介绍了模块原理、实现方法和配置步骤,并提供了两种改进方案的具体yaml配置文件。这一创新为提升目标检测性能提供了高效解决方案。

Ai缝合怪、助力小伙伴高效发论文 118

重学计算机(七、动态链接和动态库)

上一篇写的不是很好,但是也不能沉迷上一篇,把上一篇还没详细介绍的部分,通过后面的章节来介绍,这一篇介绍动态库。

酱油师兄的博客 2184

LVGL core disp显示设计(lv_disp.c)

lv_disp.c当前显示页面的配置scr_act在原始的LVGL是以screen的概念存在,但我们还是习惯叫它为一个页面提供获取top_layer、sys_layer、prev_scr图层接口配置主题管理默认的主题管理是递归查找的,实际项目中因此页面的复杂性,虽然也兼容了此主题管理的方案,但还是推荐使用单页面自行管理主题的方案壁纸设置多页面切换的动画支持计算无用户操作时间清理显示缓存。

Bigan(安)的博客 2330

chembl_webresource_client 包数据接口下载chembl数据库;ZINC数据库下载、simles获取

点击进去https://zinc.docking.org/subclasses/kinase/predictions/,然后下载sdf模式,这里可以转化simles格式,如果下载csv里面没有包含simles。参考:https://github.com/chembl/chembl_webresource_client/blob/master/demo_wrc.ipynb。参考:https://zinc.docking.org/这是网页搜索查看,16条数据。这个数据这下载特别慢。

weixin_42357472的博客 3046

Linux动态链接2:动态链接的相关结构

首先操作系统会读取可执行文件的头部,检查文件的合法性,然后从头部中的“ProgramHeader”中读取每个“Sgment”的虚拟地址、文件地址和属性,并将它们映射到进程虚拟空间的相应位置,这些步骤跟前面的静态链接情况下的装载基本无异。动态链接器在 Linux 下是 Glibc 的一部分,也就是属于系统库级别的,它的版本号往往跟系统中的 Glibc 库版本号是一样的,比如我的系统中安装的是 Glibc 2.6.1,那么相应的态链接器也就是/ib/ld-2.6.1.so。

Shujie 413

看完这篇你就能讲解LLC软开关:一文秒懂 ZVS 和 ZCS 到底啥意思!

想要 MOS 管ZVS 好实现➜ 把工作频率保持在 fr1 或更高。想让整流二极管也ZCS 实现➜ 频率就别高过 fr1。设计磁性元件时,一定要计算好 Lr、Lm、Cr 的值,这直接决定你 fr、fr1 是多少!LLC 的软开关技术不是“魔法”,是电感电容+频率控制的精妙组合;fr1 就像黄金分割点,整流和开关都能“刚刚好”;不是所有软开关都能同时实现,要看你在频率曲线的哪一段!

weixin_43199439的博客 1529

动态链接库

C语言动态链接库1. 概述1.1 静态库和动态库1.2 动态链接库的优点2. 生成动态链接库2.1 windows版本2.2 Linux版本3. 调用动态链接库3.1 windows版本3.1.1 隐式调用3.1.2 显示调用(推荐)3.2 Linux版本 1. 概述 在实际编程中,我们可以把完成某项功能的函数放在一个动态链接库里,然后提供给其他程序调用。 1.1 静态库和动态库 静态库:这类库...

liaoshenhao的博客 1万+

三菱FX系列PLC模拟量输入AD模块的使用方法和相关编程设置详解

三菱FX系列PLC模拟量输入AD模块的使用方法和相关编程设置详解

Robot_PLC_HMI_Automation 1万+

ADES1831和ADBMS6830

1、上电默认进入STANDBY模式,SPI发送0xFF也可以进入STANDBY模式2、看门狗定时器超时后,进入SLEEP状态3、配置寄存器中的REFON位使用WRCFGA命令将组A设置为1进入REFUP状态,此状态比待机状态更快地启动ADC转换。i<TOTAL_IC;i++)注意:读AFE数据时会随着AFE片数增加而增加,原因是唤醒时间和AFE片数密切相关,如果需要缩短时间,那么减少唤醒频次。

m0_61973119的博客 263

动态链接介绍

模块间的访问比模块内部稍微麻烦一点,因为模块间的数据访问目标地址要等到装载时才决定,我们前面提到要使得代码地址无关,基本的思想就是把跟地址相关的部分放到数据段里面,很明显,这些其他模块的全局变量的地址是跟模块装载地址有关的。如此循环直到所有依赖的共享对象都被装载进来为止,当然链接器可以有不同的装载顺序,如果我们把依赖关系看作一个图的话,那么这个装载过程就是一个图的遍历过程,链接器可能会使用深度优先或者广度优先或者其他的顺序来遍历整个图,这取决于链接器,比较常见的算法一般都是广度优先的。

biu801的博客 1338

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

彻底搞懂程序链接过程之动态链接

通过静态链接,可以生成一个可执行文件,这个可执行文件既可以是完全链接的也可以是部分链接的,对于部分链接的可执行文件,有些符号引用需要等到可执行文件加载时甚至是运行时才会进行符号解析和重定位。 动态链接与静态链接一样包括符号解析和重定位两个任务,静态链接和动态链接的区别之一就是符号解析和重定位的时机,动态链接分为加载时动态链接和运行时动态链接,本篇文章将拆分成3个部分阐述: 1.可执行文件的结构和加载过程。 2.加载时动态链接。 3.运行时动态链接。 可执行文件的结构和加载过程 可执行文件的结构

一口Linux的专栏 9212

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

动态链接库详解【一】

一、分别编译与链接(Linking) 大多数高级语言都支持分别编译,程序员可以显式地把程序划分为独立的模块或文件,然后每个独立部分分别编译。在编译之后,由链接器把这些独立的片段(称为编译单元)“粘接到一起”。(想想这样做有什么好处?) 在C/C++中,这些独立的编译单元包括obj文件(一般的源程序编译而成)、lib文件(静态链接的函数库)、dll文件(动态链接的函数库)等。 静态链接方式:在

一步一脚印 1万+

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

关于动态链接库及使用动态链接的优点

 关于动态链接库   动态链接允许一个模块仅需载入或执行一个导出的DLL函数。动态链接不同于我们熟悉的静态链接,使用静态链接时,链接程序会把库函数代码拷贝到每个需要的模块中。动态链接的类型  调用一个DLL中的函数有两种方法:载入时动态链接(load-time dynamic linking),模块非常明确调用某个导出函数,使得他们就像本地函数一样。这需要链接时链接那些

dtdn的专栏 7615

Linux动态链接与静态链接(详细介绍动态链接)

因此,在实际开发中,我们通常使用动态链接的方式来避免这些问题。动态链接库是为了解决静态链接库存在的缺点而被提出来的。

m0_51073072的博客 1696

动态链接器(二):使用Rust实现一个动态链接器

介绍动态链接器的功能,并提供了一个动态链接器的实现

justdoyaya的博客 1595

动态链接学习总结

代码段的不变性共享内存优势代码段通常包含程序的指令。如果多个进程可以共享相同的代码段,这将显著减少内存占用。每个进程不需要有自己的代码副本,而是共享相同的物理内存页面。优化缓存使用由于代码不变,它可以被有效地缓存,减少对内存的读取操作,提高整体性能。简化代码维护和更新如果代码段不需要针对每个使用它的进程进行修改,这简化了维护和更新共享库的过程。数据段的动态性每个进程的独立状态数据段通常包含全局变量和静态变量,这些变量的值可能在每个进程中都是不同的。

u014634649的博客 1194

载入时动态链接及运行时动态链接,译自MSDN

载入时动态链接   系统启动一个使用载入时动态链接的程序时,使用连接程序放置的到文件的信息来定位进程所需要的DLL的名称。然后系统将在以下位置顺序搜寻DLL:应用程序载入目录 当前目录 系统目录。通过GetSystemDirectory 函数可以得到。 16位系统目录。没有函数可以获取该目录,但它是被搜索的。 Windows Me/98/95: 目录不存在  Windows目录。通过GetWind

dtdn的专栏 5468
上一篇: 静态链接
下一篇: ICMP:internet控制报文协议
sicofield
博客等级 码龄18年 169粉丝 169原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值