链接库是什么

news2024/7/31 9:23:35

所谓链接库,从字面上理解,指的是程序在“链接”阶段使用的代码库。

“链接”是源程序转换成可执行程序必须经历的步骤之一,考虑到一些初学者对程序的运行过程还不了解,接下来先解释一下“链接”的含义,再系统地讲解链接库。

链接

很多编程语言写出的源代码,必须经过「编译」和「链接」这两个步骤,才能转换成可执行的程序,比如 C语言、C++、C# 等。

将源代码转换成计算机能够识别的二进制程序,这个过程叫做编译。

读者可以把编译理解成“翻译”,类似将中文翻译成英文、将英文翻译成象形文字。 编译是一个复杂的过程,大致包括词法分析、语法分析、语义分析、性能优化、生成二进制代码五个步骤,期间涉及到复杂的算法和硬件架构,感兴趣的读者请自行阅读《编译原理》一书,这里我们不再展开讲解。

编译源代码后生成的文件叫做目标文件(Object File),例如 Visual Studio 下的.obj,或者 GCC 下的.o,它们都是目标文件。注意,目标文件里存储的二进制代码还不完整,不能直接运行。

实际开发中软件的规模往往都很大,动辄数百万行代码,为了方便阅读和维护,程序员会把它们分散到多个文件里。每个文件存储的都是源代码片段,编译它们会生成多个目标文件,这些文件中存储的都是二进制代码片段,每个都不完整,所以不能直接运行。

即便将所有的源代码写在一个源文件里,编译生成一个目标文件,文件中的二进制代码还是不能运行,因为缺少运行所需要的系统组件(比如标准库、链接库等)。

所有目标文件里的二进制代码,以及运行所需要的系统组件(比如标准库、链接库等),把它们组合到一起的过程就叫做链接。链接完成后会生成一个可执行文件,里边存储的就是可执行程序。

你看,程序的链接阶段确实会用到链接库。

关于编译和链接的具体细节,不再深入讲解,感兴趣的读者可以阅读《编译和链接》模块。

链接库

链接库是库的一种,它存放的不是源代码,而是编译后生成的二进制代码。

链接库自己是没法运行的,必须等待别的程序在链接阶段调用它,然后它们一起组合成可执行程序。这样当可执行程序运行时,链接库的程序就能运行了。

链接库的组合方式有两种,分别是:

  1. 直接把链接库中的代码和数据拷贝一份,添加到可执行文件中。最终生成的可执行程序,包含要运行的所有代码,能够脱离链接库独自运行,这样的组合方法叫做静态链接;
  2. 先把所有目标文件组合成一个可执行文件,文件中缺少链接库的代码和数据,不能脱离链接库独立运行。换句话说,程序运行时必须和链接库一起载入到内存中,然后它们在内存中组合成完整的代码,才能正常运行,这样的组合方法叫做动态链接。


也就是说,静态链接是程序载入内存之前完成的,而动态链接是将链接的时机推迟到程序载入内存之后完成。采用静态链接方式的库叫做静态链接库,采用动态链接方式的库叫做动态链接库。

动态链接库是 Windows 平台的叫法,Linux 平台上习惯叫做共享库或者共享对象文件,它们表达的是一个意思。

静态链接库

调用静态链接库生成的可执行程序,程序中包含链接库所有的代码和数据,所以它可以脱离链接库独自运行。

在 Windows 环境中,静态链接库的后缀名通常是.lib;在 Linux 环境中,静态链接库的后缀名通常是.a

调用静态链接库有很多好处,比如可执行程序能够在没有链接库的环境中运行,程序移植到其它的系统环境时不需要额外安装和配置链接库,链接库版本发生变化也不会对程序造成影响等。

静态链接库也存在一些弊端,比如:

  • 由于链接库的代码和数据复制到了可执行文件中,当程序功能较为复杂的时候,整个文件的体积会非常大,加载到内存中的时间就会比较长,最直接的一个例子就是双击打开一个软件,要很久才能看到界面,非常影响用户体验;
  • 当静态链接库需要更新时,所有调用此链接库的可执行程序都需要重新编译和链接,大大增加了维护的工作量;
  • 对于运行着的多个程序,如果它们调用的是同一个静态链接库,那么链接库的代码和数据在内存中就会出现很多份,造成了内存资源的浪费。


实际场景中,如果强调程序能够脱离链接库独自运行,避免不同的系统环境影响程序的正常运行,那么静态链接库是不错的选择;反之,如果链接库需要频繁更新、或者强调对内存资源的高效利用,静态链接库就不适合了。

动态链接库

调用动态链接库生成的可执行程序,程序中不包含链接库的代码和数据,所以程序无法脱离链接库独自运行。换句话说,程序要想执行,必须连同动态链接库一起载入到内存中。

在 Windows 环境下,动态链接库的后缀名通常是.dll;在 Linux 环境下,动态链接库的后缀名通常是.so

动态链接库载入内存的方式有两种,分别是:

  • 隐式加载:又叫载入时加载,指的是可执行程序载入内存时搜索动态链接库,并将链接库的代码和数据载入内存;
  • 显式加载:又叫运行时加载,指的是可执行程序在运行过程中,需要动态链接库里的代码和数据时再加载。


隐式加载也会有静态链接库的问题,如果程序稍大,加载时间就会过长,用户不能接受。显式加载则不存在这个问题,它是将较大的程序分开加载的,程序运行时只需要将可执行程序载入内存,后续需要再载入动态链接库,软件打开速度快,用户体验好。

关于隐式加载和显式加载动态链接库的具体实现,后续章节会做详细地讲解。

和静态链接库相比,动态链接库可以很好地解决空间浪费和更新困难的问题。

动态链接库和可执行文件是分开载入内存的,当有多个程序调用同一个动态链接库时,所有程序共享一份动态链接库的代码和数据,有效避免了内存资源的浪费。

当可执行程序调用的动态链接库需要更新或者升级时,直接用新的库文件把旧的替换掉,程序运行时会自动载入新的动态链接库。

有读者可能会问,采用动态链接的方式,程序每次运行都需要重新链接,会不会很慢?的确,动态链接确实会损失一部分程序性能,但实践证明,动态链接库和静态链接相比,性能损失大约在 5% 以下,由此换取程序在空间上的节省以及更新时的便利,是相当值得的。

总结

链接库指的就是程序在链接阶段使用的代码库。

程序载入内存之前完成链接工作的,称为静态链接库;程序载入内存以后完成链接工作的,称为动态链接库。

静态链接库和动态链接库各有优缺点,要根据实际的项目需求和约束条件选择合适的链接方式。

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

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

相关文章

Ajax从零到实战

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…

RK3568笔记三十三: helloworld 驱动测试

若该文为原创文章,转载请注明原文出处。 报着学习态度,接下来学习驱动是如何使用的,从简单的helloworld驱动学习起。 开始编写第一个驱动程序—helloworld 驱动。 一、环境 1、开发板:正点原子的ATK-DLRK3568 2、系统&#xf…

Spring源码二十二:Bean实例化流程五

上一篇Spring源码二十一:Bean实例化流程四,咱们主要分析里createBeanInstance方法Spring给我们提供给的FactoryMethod方法,举例说明了factoryMethod属性如何使用,同时简单讨论了具体实现逻辑。 这一篇咱们将进入反射实例化Bean&am…

JavaEE初阶-网络原理2

文章目录 前言一、TCP报头结构二、TCP的十个核心机制2.1 确认应答2.2 超时重传2.3 连接管理2.3.1 建立连接:三次握手2.3.2 断开连接:四次挥手. 2.4 滑动窗口2.5 流量控制2.6 拥塞控制2.7 延时应答2.8 捎带应答2.9 面向字节流2.10 异常情况2.11 补充 前言…

OpenCV漫水填充函数floodFill函数的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 功能描述 ffloodFill函数是OpenCV库中用于图像处理的一个功能,它用于填充与种子点颜色相近的连通区域。这个函数在很多场景下都非常有用&#x…

基于 BERT 的非结构化领域文本知识抽取

文章目录 题目摘要方法实验 题目 食品测试的大型语言模型 论文地址:https://arxiv.org/abs/2103.00728 摘要 随着知识图谱技术的发展和商业应用的普及,从各类非结构化领域文本中提取出知识图谱实体及关系数据的需求日益增加。这使得针对领域文本的自动化…

MySQL学习(9):多表查询

1.多表关系 1.1一对多 1.2多对多 1.3一对一 设置外键唯一,是为了让两张表的数据一一对应 2.多表查询 2.1多表查询案例 现有父表(dept)如下: 子表(emp)如下: 让子表的dept_id作为外键与主表的…

重要文件放u盘还是硬盘?硬盘和u盘哪个适合长期存储

在数字时代,我们每天都会处理大量的文件。其中,不乏一些对我们而言至关重要的文件,如家庭照片、工作文档、财务记录等。面对这些重要文件的存储问题,我们通常会面临:“重要文件放U盘还是硬盘”、“硬盘和U盘哪个适合长…

辐射神经场算法——Instant-NGP / Mipi-NeRF 360 / 3D Gaussian Splatting

辐射神经场算法——Instant-NGP / Mipi-NeRF 360 / 3D Gaussian Splatting 1. Instant-NGP1. MultiResolution Hash Encoding1.2 Accelerated Ray Marching1.3 实验结果 2. Mip-NeRF 3602.1 场景参数化2.2 在线蒸馏2.3 失真正则化2.4 实验结果 3. 3D Gaussian Splatting3.1 Dif…

盲人出行好帮手:蝙蝠避障让走路变简单

在一片无光的世界里,每一步都承载着探索与勇气。我是众多盲人中的一员,每天的出行不仅是从A点到B点的物理移动,更是一场心灵的征程。我的世界,虽然被剥夺了视觉的馈赠,却因科技的力量而变得宽广…

kibana连接elasticsearch(版本8.11.3)

前言 elasticsearch在8版本之后就出现了很大变化,由于kibana版本需要需elasticsearch进行版本对象,kibana连接方式也出现了很大变化。我在这里记录下自己的踩坑记录。 服务部署 本文中的服务都是在docker环境中部署的。其中elasticsearch版本和kibana版…

手机被删除的短信怎么恢复?3个专家级恢复指南,拯救你的短信

想象一下,你正在翻阅一本尘封已久的日记,突然,几页重要的篇章不见了。那种失落和焦虑,想必与失去手机短信的感觉不相上下。 手机短信作为一种传统的通讯方式,仍然承载着我们的许多重要回忆和关键信息。被删除的短信怎…

Java | Leetcode Java题解之第225题用队列实现栈

题目&#xff1a; 题解&#xff1a; class MyStack {Queue<Integer> queue;/** Initialize your data structure here. */public MyStack() {queue new LinkedList<Integer>();}/** Push element x onto stack. */public void push(int x) {int n queue.size();…

企业如何选择平滑替代传统的FTP系统呢?

面对现在数据量的激增和网络安全威胁的不断演变&#xff0c;许多传统企业在用传统的FTP系统都面对着许多的安全和传输问题&#xff0c;原系统已经逐步无法满足现代企业的需求&#xff0c;今天小编将深入细讨企业为什么需要替代FTP系统的原因&#xff0c;以及如何选择合适企业的…

昇思MindSpore学习笔记6-06计算机视觉--Vision Transormer图像分类

摘要&#xff1a; 记录MindSpore AI框架使用ViT模型在ImageNet图像数据分类上进行训练、验证、推理的过程和方法。包括环境准备、下载数据集、数据集加载、模型解析与构建、模型训练与推理等。 一、概念 1. ViT模型 Vision Transformer 自注意结构模型 Self-Attention Tran…

CSS3实现彩色变形爱心动画【附源码】

随着前端技术的发展&#xff0c;CSS3 为我们提供了丰富的动画效果&#xff0c;使得网页设计更加生动和有趣。今天&#xff0c;我们将探讨如何使用 CSS3 实现一个彩色变形爱心加载动画特效。这种动画不仅美观&#xff0c;而且可以应用于各种网页元素&#xff0c;比如加载指示器或…

【数据结构】线性表----队列详解

1. 队列的基本概念 话不多说&#xff0c;直接开始&#xff01; 队列是一种线性数据结构&#xff0c;同栈类似但又不同&#xff0c;遵循先进先出&#xff08;FIFO, First In First Out&#xff09;的原则。换句话说&#xff0c;最先进入队列的元素会最先被移除。这样的特点使得…

MyBatis拦截器在实际项目中的应用

MyBatis 是一个流行的 Java 持久层框架&#xff0c;它简化了数据库访问的复杂性&#xff0c;为开发者提供了强大的功能。其中&#xff0c;MyBatis 拦截器是一个非常有用的特性&#xff0c;可以帮助开发者灵活地解决各种问题。 一、MyBatis 拦截器 1.1 从执行 SQL 语句的核心流…

力扣爆刷第163天之TOP100五连刷81-85(回文链表、路径和、最长重复子数组)

力扣爆刷第163天之TOP100五连刷81-85&#xff08;回文链表、路径和、最长重复子数组&#xff09; 文章目录 力扣爆刷第163天之TOP100五连刷81-85&#xff08;回文链表、路径和、最长重复子数组&#xff09;一、234. 回文链表二、112. 路径总和三、169. 多数元素四、662. 二叉树…

sort命令

简介 sort是在Linux里非常常用的一个排序命令。将文件的每一行作为一个单位&#xff0c;从首字符向后&#xff0c;依次按ASCII码值进行比较&#xff0c;默认将他们按升序输出。 常用参数 -u &#xff1a;去除重复行 -r &#xff1a;降序排列&#xff0c;默认是升序 …