库的概念:动态库与静态库

在软件开发中,库是代码复用的核心工具,它帮助开发者避免重复造轮子,提升开发效率。库可以分为动态库和静态库,这两者在程序开发中的使用方式、链接过程和性能上存在显著区别。本文将详细讲解动态库与静态库的定义、区别、链接过程以及它们的实际应用场景。


一、什么是库?

库是一组封装好的函数或方法,它们可以被多个程序复用,从而避免重复编写相同功能的代码。例如,标准的数学函数库、字符串操作库都属于常用的库。

根据链接方式的不同,库可以分为静态库和动态库。

1. 动态库

动态库(Dynamic Library)是一种在程序运行时被加载的库。

  • 文件格式
    • Linux 下的动态库后缀为 .so(Shared Object)。
    • Windows 下的动态库后缀为 .dll(Dynamic Link Library)。
  • 特点
    • 动态库在运行时加载,而不是在编译时嵌入到程序中。
    • 程序运行时依赖动态库,需确保动态库在正确的路径下。

2. 静态库

静态库(Static Library)是一种在编译时直接嵌入到程序中的库。

  • 文件格式
    • Linux 下的静态库后缀为 .a(Archive)。
    • Windows 下的静态库后缀为 .lib
  • 特点
    • 静态库在编译阶段被复制到程序中,生成的可执行文件中包含库的内容。
    • 程序运行时不需要外部库的支持。

二、动态库与静态库的链接过程

1. 动态库的链接过程

动态库的链接发生在程序运行时,操作系统会动态加载动态库并解析符号地址。

过程示例

printf("Hello, world!\n") 为例:

  1. 程序调用 printf 函数。
  2. 链接器根据符号表查找 printf 所在的动态库(如 libc.so)。
  3. 链接器定位 libc.soprintf 的内存地址。
  4. 程序跳转到对应内存地址执行 printf 函数。
优点
  • 节省磁盘和内存空间:多个程序可以共享同一个动态库。
  • 便于更新:更新动态库时无需重新编译程序。
缺点
  • 运行时依赖性:程序运行时必须确保动态库存在。
  • 启动性能稍低:运行时需要加载和解析动态库。
示例命令
gcc main.o -o main -L. -lhello -Wl,-rpath=.
  • -L.:指定动态库路径。
  • -lhello:链接动态库 libhello.so
  • -Wl,-rpath=.:指定运行时动态库的搜索路径。

2. 静态库的链接过程

静态库的链接发生在编译时,链接器将静态库中的目标代码直接嵌入到可执行文件中。

过程示例

printf("Hello, world!\n") 为例:

  1. 编译阶段,链接器将 libc.aprintf 的代码嵌入到程序中。
  2. 程序中已经包含了 printf 的实现,运行时无需依赖外部库。
优点
  • 运行时独立性:程序运行时不依赖外部库。
  • 适合嵌入式开发:在资源受限的环境中非常实用。
缺点
  • 占用磁盘空间:每个程序都包含库的副本,导致可执行文件体积较大。
  • 更新复杂:若库更新,需要重新编译所有依赖该库的程序。
示例命令
gcc main.o -o main -L. -lhello -static
  • -static:强制使用静态库进行链接。

三、动态库与静态库的本质

动态库与静态库的本质都是目标文件(.o 文件)的集合,区别在于它们的链接时机和使用方式,主要区别于程序运行时

1. 静态库的本质

静态库是将多个目标文件打包成一个归档文件(如 .a.lib)。

创建静态库
gcc -c hello.c -o hello.o
ar rcs libhello.a hello.o
  • ar rcs:创建静态库。
使用静态库
gcc main.o -o main -L. -lhello

当程序被加载进内存前,程序中的方法代码就已经通过静态库对应的代码进行替换嵌入了,所以当加载进内存后的程序大小就包括了所有嵌入的代码,会明显感受到静态链接的程序比动态链接的程序大很多。


2. 动态库的本质

动态库是将多个目标文件打包成一个共享库文件(如 .so.dll)。

创建动态库
gcc -fPIC -c hello.c -o hello.o
gcc -shared -o libhello.so hello.o
  • -fPIC:生成与地址无关的代码。
  • -shared:生成动态库。
使用动态库
gcc main.o -o main -L. -lhello -Wl,-rpath=.

使用动态库动态链接的程序在加载进内存中时,动态库与程序一起加载到内存中。因为链接时是用动态库中关于程序中所需要的代码的地址进行链接,直接在库中进行运行后然后返回到程序,所以只需要加载进内存一份动态库,会节省很多内存。


四、动态库与静态库的对比

特性静态库动态库
文件格式.a(Linux),.lib(Windows).so(Linux),.dll(Windows)
链接时间编译时运行时
占用空间程序体积较大,库内容被复制到程序中程序体积小,库不被复制到程序中
更新方式需重新编译程序动态库可独立更新,无需重新编译
性能高(不需要运行时加载库)稍低(运行时需加载和解析库)

五、动态库与静态库的实际应用

1. 动态库的应用场景

  • 共享库:多个程序需要共享同一组函数或方法。
  • 库频繁更新:需要更新库的实现而不影响依赖库的程序。
  • 节省内存:适合运行多个实例的服务端程序。

2. 静态库的应用场景

  • 嵌入式开发:在没有动态库支持的环境中使用。
  • 独立运行:需要生成完全独立的可执行文件。
  • 简单部署:无需额外安装动态库即可运行。

六、总结

动态库和静态库各有优缺点,选择使用哪种库需要根据具体的项目需求来权衡。

区别:

  • 动态库:节省磁盘和内存资源,便于更新,但运行时依赖性较强。
  • 静态库:程序运行时独立性强,适合资源受限的环境,但程序体积较大。

无论是动态库还是静态库,它们的核心本质都是目标文件的集合,通过不同的链接方式为程序提供功能支持。理解它们的特点和使用方法,可以帮助开发者更高效地管理和复用代码资源。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flink源码解析之:如何根据JobGraph生成ExecutionGraph

Flink源码解析之:如何根据JobGraph生成ExecutionGraph 在上一篇Flink源码解析中,我们介绍了Flink如何根据StreamGraph生成JobGraph的流程,并着重分析了其算子链的合并过程和JobGraph的构造流程。 对于StreamGraph和JobGraph的生成来说&…

风力涡轮机缺陷检测数据集,91.4%准确识别率,18912张图片,支持yolo,PASICAL VOC XML,COCO JSON格式的标注

风力涡轮机缺陷检测数据集,91.4%准确识别率,18912张图片,支持yolo,PASICAL VOC XML,COCO JSON格式的标注 数据集下载: yolo v&#…

系统设计——大文件传输方案设计

摘要 大文件传输是指通过网络将体积较大的文件从一个位置发送到另一个位置的过程。这些文件可能包括高清视频、大型数据库、复杂的软件安装包等,它们的大小通常超过几百兆字节(MB)甚至达到几个吉字节(GB)或更大。大文…

linux中执行命令

1.1 命令格式 命令格式: 主命令 选项 参数(操作对象) 命令分为两类: 内置命令( builtin ):由 shell 程序自带的命令 外部命令:有独立的可执行程序文件,文件名即命令…

Elasticsearch:当混合搜索真正发挥作用时

作者:来自 Elastic Gustavo Llermaly 展示混合搜索何时优于单独的词汇或语义搜索。 在本文中,我们将通过示例探讨混合搜索,并展示它与单独使用词汇或语义搜索技术相比的真正优势。 什么是混合搜索? 混合搜索是一种结合了不同搜索…

Python pyside6 设置的一个《广告图片生成器》

一、图: 二、说明书: 广告图片生成器使用说明 软件功能 这是一个用于生成广告图片的工具,可以快速制作包含产品图片和文字的广告图片。 主要特点 自定义广告尺寸(默认620420像素) 智能去除产品图片背景 自动排版&…

Spark基本介绍

一,Spark是什么 1.定义:Aache Spark是用于大规模数据处理的统一分析引擎。 二,Spark的发展 三,Spark的特点 高效性 计算速度快 提供了一个全新的数据结构RDD(弹性分布式数据集)。整个计算操作,…

Elasticsearch操作笔记版

文章目录 1.ES索引库操作(CRUD)1.mapping常见属性(前提)2.创建索引库3.查询,删除索引库4.修改索引库 2.ES文档操作(CRUD)1.新增文档2.查询、删除文档查询返回的数据解读: 3.修改文档 3.RestClient操作(索引库/文档)(CRUD)1.什么是RestClient2.需要考虑前…

EFEVD: Enhanced Feature Extraction for Smart Contract Vulnerability Detection

假设,攻击者在合约 Dao 内存放有 1 Ether 攻击者调用 withdraw 函数,提取 1 Ether; 函数执行到 require 之后, balances 之前时,6789-6789-6789- contract Dao {function withdraw() public {require(balances[msg.…

我的线代观-秩(向量,矩阵)

都说秩是线代中不可避免的一环,当然,它其中最重要的一环。 我在学习线代之后,也有这种感受,它有着一种很绕的感受。 1.矩阵中 在矩阵中,它的秩是怎么定义的呢。它常常与行列式扯上关系,我们拿三阶矩阵为例…

ES IK分词字典热更新

前言 在使用IK分词器的时候,发现官方默认的分词不满足我们的需求,那么有没有方法可以自定义字典呢? 官方提供了三种方式 一、ik本地文件读取方式 k插件本来已为用户提供自定义词典扩展功能,只要修改配给文件即可: …

基于Spring Boot的电影网站系统

一、技术架构 后端框架:Spring Boot,它提供了自动配置、简化依赖管理、内嵌式容器等特性,使得开发者可以快速搭建起一个功能完备的Web应用。 前端技术:可能采用Vue.js、JS、jQuery、Ajax等技术,结合Element UI等组件库…

C#运动控制系统:雷赛控制卡实用完整例子 C#雷赛开发快速入门 C#雷赛运动控制系统实战例子 C#快速开发雷赛控制卡

雷赛控制技术 DMC系列运动控制卡是一款新型的 PCI/PCIe 总线运动控制卡。可以控制多个步进电机或数字式伺服电机;适合于多轴点位运动、插补运动、轨迹规划、手轮控制、编码器位置检测、IO 控制、位置比较、位置锁存等功能的应用。 DMC3000 系列卡的运动控制函数库功…

android studio 写一个小计时器(版本二)

as版本&#xff1a;23.3.1patch2 例程&#xff1a;timer 在前一个版本的基本上改的&#xff0c;增加了继续的功能&#xff0c;实现方法稍微不同。 动画演示&#xff1a; activity_main.xml <?xml version"1.0" encoding"utf-8"?> <androidx…

python-leetcode-轮转数组

189. 轮转数组 - 力扣&#xff08;LeetCode&#xff09; class Solution:def rotate(self, nums: List[int], k: int) -> None:"""Do not return anything, modify nums in-place instead."""n len(nums)k % n # 如果 k 大于 n&#xff0c;…

亚马逊云科技 | Amazon Nova:智能技术新势力

在2024年亚马逊云科技re:invent大会上&#xff0c;Amazon Nova 系列自研生成式 AI 多模态模型重磅登场&#xff0c;新一代的AI产品-Amazon Nova&#xff0c;隶属于 Amazon Bedrock&#xff0c;一共发布6款大模型&#xff0c;精准切入不同领域&#xff0c;解锁多元业务可能&…

记录第一次跑YOLOV8做目标检测

今天是24年的最后一天&#xff0c;终于要向新世界开始破门了&#xff0c;开始深度学习&#xff0c;YOLO来敲门~ 最近做了一些皮肤检测的功能&#xff0c;在传统的处理中经历了反复挣扎&#xff0c;终于要上YOLO了。听过、看过&#xff0c;不如上手体会过~ 1、YOLO是什么&#x…

从授权校验看SpringBoot自动装配

背景 最近需要实现一个对于系统的授权检测功能&#xff0c;即当SpringBoot应用被启动时&#xff0c;需要当前设备是否具有有效的的授权许可信息&#xff0c;若无则直接退出应用。具体的实现方案请继续看下文。 环境 Ruoyi-Vue SpringBoot3 RuoYi-Vue: &#x1f389; 基于Spr…

【Unity】 HTFramework框架(五十七)通过Tag、Layer批量搜索物体

更新日期&#xff1a;2024年12月30日。 Github源码&#xff1a;[点我获取源码] Gitee源码&#xff1a;[点我获取源码] 索引 问题再现通过Tag搜索物体&#xff08;SearchByTag&#xff09;打开SearchByTag窗口搜索标记指定Tag的所有物体批量修改Tag搜索Undefined状态的所有物体 …

Unity2D无限地图的实现(简单好抄)

说明&#xff1a;本教程实现的是在2D游戏中玩家在游戏中上下左右移动的时候自动进行地图拼接的功能&#xff0c;如果你只想实现左右移动的无限地图&#xff0c;那么这篇博客也能起到一定参考作用。 思路 第一步&#xff1a; 创建一个10*10的2D游戏对象当做地图 第二步创建一个…