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

【Linux探索学习】第二十五弹——动静态库:Linux 中静态库与动态库的详细解析

Linux学习笔记:

https://blog.csdn.net/2301_80220607/category_12805278.html?spm=1001.2014.3001.5482

前言:

在 Linux 系统中,静态库和动态库是开发中常见的两种库文件类型。它们在编译、链接、内存管理以及程序的性能和可维护性方面有着显著的差异。了解静态库与动态库的区别和使用方式,有助于开发者根据实际需求选择最适合的解决方案。本文将详细介绍静态库与动态库的概念、差异、使用方法,并通过实际的代码示例讲解如何创建和使用这些库。

目录

  1. 静态库与动态库的基本概念

    • 静态库(Static Library)
    • 动态库(Dynamic Library)
  2. 静态库与动态库的区别

    • 编译与链接时机
    • 文件格式与大小
    • 性能与内存管理
    • 使用场景
  3. 如何在 Linux 中创建静态库

    • 创建静态库的步骤
    • 静态库的使用示例
    • 静态库的优缺点
  4. 如何在 Linux 中创建动态库

    • 创建动态库的步骤
    • 动态库的使用示例
    • 动态库的优缺点
  5. 静态库与动态库的优缺点比较

    • 性能方面
    • 存储与内存使用
    • 依赖管理
  6. 动态库的加载与链接机制

    • 静态链接与动态链接的概念
    • 动态库的查找机制
  7. 静态库与动态库的底层实现

    • 静态库的实现机制
    • 动态库的实现机制
  8. 进阶话题

    • 如何处理库版本
    • 库文件的符号表与重定位
    • 库的跨平台使用

1. 静态库与动态库的基本概念

静态库(Static Library)

静态库是一种在编译时就将代码和资源打包到可执行文件中的库。静态库通常是由多个目标文件(.o 文件)组成的,最终在编译时会将这些目标文件的代码合并到程序的可执行文件中。静态库的扩展名通常为 .a

静态库的特点

  • 在编译时将库文件的代码直接嵌入到可执行文件中。
  • 每个程序都需要自己链接一份静态库的副本。
  • 不需要在程序运行时进行额外的文件查找或加载。
  • 编译过程中会把库的所有代码复制到目标文件中,增加了可执行文件的体积。
动态库(Dynamic Library)

动态库是一种在程序运行时加载的共享库。与静态库不同,动态库的代码不会在编译时直接嵌入到可执行文件中,而是在程序运行时通过动态链接器加载。动态库通常具有 .so(Shared Object)扩展名。

动态库的特点

  • 在程序运行时由操作系统动态加载。
  • 可以被多个程序共享,减少了内存和磁盘空间的消耗。
  • 不需要在编译时复制代码,程序的大小较小。
  • 在程序运行时,可以更新动态库,而不需要重新编译所有依赖该库的程序。

2. 静态库与动态库的区别

特性静态库(Static Library)动态库(Dynamic Library)
文件扩展名.a.so
编译时机在编译时静态链接在运行时动态加载
链接方式静态链接(编译时)动态链接(运行时)
程序体积较大,库的代码嵌入程序中较小,库的代码不嵌入程序中
内存管理每个程序都拥有库的副本多个程序共享库的副本
依赖管理依赖是固定的,程序与库紧耦合依赖管理灵活,库的更新不需要重新编译
更新更新需要重新编译所有依赖的程序只需更新动态库,不需要重新编译程序
使用场景不需要动态链接支持的独立应用需要共享库、多程序共享资源的场景
编译与链接时机
  • 静态库的链接发生在编译时。编译器会将库文件的所有目标文件内容复制到程序中,生成一个包含所有必要代码的可执行文件。
  • 动态库的链接发生在程序运行时。动态链接器会在程序启动时加载所需的共享库,并将其中的符号解析并链接到程序中。
文件格式与大小
  • 静态库通常是 .a 格式,文件较大,因为它包含了库中所有的目标文件(.o 文件)。
  • 动态库通常是 .so 格式,文件较小,多个程序可以共享同一个动态库。
性能与内存管理
  • 静态库的程序在运行时不需要加载额外的库文件,因为它们已经嵌入到可执行文件中,程序启动时性能较好。
  • 动态库的程序在运行时需要加载外部库文件,虽然加载过程可能略有延迟,但多个程序可以共享同一个动态库,节省内存和磁盘空间。
使用场景
  • 静态库适合小型应用程序和嵌入式系统,特别是当程序不依赖于大量外部库时。
  • 动态库适合大型系统或需要频繁更新的应用程序,因为库更新不需要重新编译应用程序。

3. 如何在 Linux 中创建静态库

创建静态库的步骤
  1. 编写源代码: 创建一个简单的 C 文件,定义一些函数:

    // mathlib.c
    #include <stdio.h>int add(int a, int b) {return a + b;
    }int subtract(int a, int b) {return a - b;
    }
    
  2. 编译为目标文件: 使用 gcc 将 C 文件编译为目标文件:

    gcc -c mathlib.c -o mathlib.o
    
  3. 创建静态库: 使用 ar 工具将目标文件打包成静态库:

    ar rcs libmath.a mathlib.o
    
  4. 使用静态库: 创建一个程序来调用这个静态库:

    // main.c
    #include <stdio.h>int add(int, int);
    int subtract(int, int);int main() {printf("Sum: %d\n", add(5, 3));printf("Difference: %d\n", subtract(5, 3));return 0;
    }
    

    编译并链接静态库:

    gcc main.c -L. -lmath -o main
    
  5. 运行程序

    ./main
    
静态库的优缺点

优点

  • 不需要依赖外部库,程序独立性强。
  • 程序启动速度较快。

缺点

  • 程序文件较大,内存占用较高。
  • 如果库有更新,所有依赖该库的程序都需要重新编译。

4. 如何在 Linux 中创建动态库

创建动态库的步骤
  1. 编写源代码

    // mathlib.c
    #include <stdio.h>__attribute__((visibility("default"))) int add(int a, int b) {return a + b;
    }__attribute__((visibility("default"))) int subtract(int a, int b) {return a - b;
    }
    
  2. 编译为共享库: 使用 gcc 将代码编译为动态库:

    gcc -fPIC -shared mathlib.c -o libmath.so
    
  3. 使用动态库: 创建一个主程序,调用动态库中的函数:

    // main.c
    #include <stdio.h>int add(int, int);
    int subtract(int, int);int main() {printf("Sum: %d\n", add(5, 3));printf("Difference: %d\n", subtract(5, 3));return 0;
    }
    

    编译并链接动态库:

    gcc main.c -L. -lmath -o main
    
  4. 设置动态库路径并运行程序

    export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
    ./main
    
动态库的优缺点

优点

  • 可以在程序运行时加载,多个程序共享同一个库。
  • 更新库时无需重新编译依赖程序,降低了维护成本。

缺点

  • 程序启动时需要加载外部库,可能会稍慢。
  • 如果程序依赖的库丢失或版本不兼容,可能会导致运行时错误。

5. 静态库与动态库的优缺点比较

特性静态库动态库
程序大小较大,库的代码嵌入到程序中较小,多个程序共享同一份库
内存使用每个程序都需要加载一份库的副本多个程序共享同一份库,节省内存
启动速度较快,不需要加载外部库文件稍慢,需要加载外部库文件
依赖管理静态,程序与库紧密耦合动态,程序可以独立于库更新
更新需要重新编译所有依赖的程序只需更新库文件,无需重新编译程序

6. 动态库的加载与链接机制

动态库的加载和链接分为两种方式:编译时动态链接(Compile-time Linking)和运行时动态链接(Runtime Linking)。

编译时动态链接

编译时动态链接指的是在编译时指定使用的动态库,编译器会将库的符号信息嵌入到可执行文件中。程序运行时,操作系统会加载对应的动态库。

运行时动态链接

运行时动态链接是指程序通过 dlopen() 等系统调用在运行时加载库文件。这种方式更为灵活,可以根据需要加载不同的库。

7. 静态库与动态库的底层实现

  • 静态库:静态库文件实际上是一个归档文件,里面包含了一些目标文件(.o 文件)。当程序需要使用静态库时,链接器会从静态库中提取所需的目标文件,并将它们嵌入到可执行文件中。
  • 动态库:动态库文件是一个共享对象,包含了可以在多个程序中共享的代码。操作系统通过动态链接器(如 Linux 上的 ld.so)负责加载动态库并解析符号。

8. 进阶话题

如何处理库版本

库的版本管理对于动态库尤为重要。常见的方法是使用符号链接或者版本控制机制来管理不同版本的动态库。

库文件的符号表与重定位

库文件中的符号表包含了函数和变量的符号信息。链接器会根据符号表进行符号解析和重定位。

库的跨平台使用

动态库的跨平台使用通常依赖于编译时指定的架构和平台。使用如 autoconfCMake 等工具可以帮助开发者更好地进行跨平台构建。


结论

静态库与动态库在 Linux 系统中的应用各有优势与劣势。静态库适用于需要独立性较强的程序,而动态库则适用于内存共享和版本更新更加灵活的场景。在实际开发中,开发者应根据应用的需求、维护成本和性能要求来选择合适的库类型。

本篇笔记:


感谢各位大佬观看,创作不易,还请各位大佬点赞支持!!!

相关文章:

【Linux探索学习】第二十五弹——动静态库:Linux 中静态库与动态库的详细解析

Linux学习笔记&#xff1a; https://blog.csdn.net/2301_80220607/category_12805278.html?spm1001.2014.3001.5482 前言&#xff1a; 在 Linux 系统中&#xff0c;静态库和动态库是开发中常见的两种库文件类型。它们在编译、链接、内存管理以及程序的性能和可维护性方面有着…...

远程和本地文件的互相同步

文章目录 1、rsync实现类似git push pull功能1. 基础概念2. 示例操作3. 定制化和进阶用法4. 定时同步&#xff08;类似自动化&#xff09; 2 命令简化1. 动态传参的脚本2. Shell 函数支持动态路径3. 结合环境变量和参数&#xff08;更简洁&#xff09;4. Makefile 支持动态路径…...

自然语言处理之jieba分词和TF-IDF分析

jieba分词和TF-IDF分析 目录 jieba分词和TF-IDF分析1 jieba1.1 简介1.2 终端下载1.3 基本语法 2 TF-IDF分析2.1 什么是语料库2.2 TF2.3 IDF2.4 TF-IDF2.5 函数导入2.6 方法 3 实际测试3.1 问题解析3.2 代码测试 1 jieba 1.1 简介 结巴分词&#xff08;Jieba&#xff09;是一个…...

探索式测试

探索式测试是一种软件测试风格&#xff0c;它强调独立测试人员的个人自由和职责&#xff0c;为了持续优化其工作的价值&#xff0c;将测试学习、测试设计、测试执行和测试结果分析作为相互支持的活动&#xff0c;在整个项目实现过程中并行地执行。 选择合适的探索式测试方法我…...

服务器数据恢复—raid5故障导致上层ORACLE无法启动的数据恢复案例

服务器数据恢复环境&故障&#xff1a; 一台服务器上的8块硬盘组建了一组raid5磁盘阵列。上层安装windows server操作系统&#xff0c;部署了oracle数据库。 raid5阵列中有2块硬盘的硬盘指示灯显示异常报警。服务器操作系统无法启动&#xff0c;ORACLE数据库也无法启动。 服…...

ISP各模块功能介绍

--------声明&#xff0c;本文为转载整理------- ISP各个模块功能介绍&#xff1a; 各模块前后效果对比&#xff1a; 黑电平补偿&#xff08;BLC&#xff09; 在理想情况下&#xff0c;没有光照射的像素点其响应值应为0。但是&#xff0c;由于杂质、受热等其它原因的影响&…...

Python 数据建模完整流程指南

在数据科学和机器学习中&#xff0c;建模是一个至关重要的过程。通过有效的数据建模&#xff0c;我们能够从原始数据中提取有用的洞察&#xff0c;并为预测或分类任务提供支持。在本篇博客中&#xff0c;我们将通过 Python 展示数据建模的完整流程&#xff0c;包括数据准备、建…...

深入学习RocketMQ

参考&#xff1a;RocketMQ从从入门到精通_rocketmq入门到精通-CSDN博客 1、消息的类型 普通消息 顺序消息 延时消息 批量消息 事务消息 2、在java中使用 2.1、pom.xml中加入依赖 <dependency><groupId>org.apache.rocketmq</groupId><artifactId…...

国产编辑器EverEdit - 扩展脚本:关闭所有未修改文档

1 扩展脚本&#xff1a;关闭所有未修改文档 1.1 应用场景 当用户打开过多文档时&#xff0c;部分文档已经修改&#xff0c;而大部分没有修改&#xff0c;为了减少在众多已打开文档中来回跳转的不便&#xff0c;可以将没有修改的文档全部关闭&#xff0c;但目前提供的快速关闭窗…...

数据结构二叉树-C语言

数据结构二叉树-C语言 1.树1.1树的概念与结构1.2树的相关术语1.3树的表示1.4树形结构实际运用场景 2.二叉树2.1概念与结构2.2特殊的二叉树2.2.1满二叉树2.2.2完全二叉树 2.3二叉树存储结构2.3.1顺序结构2.3.2链式结构 3.实现顺序结构的二叉树4.实现链式结构二叉树4.1前中后序遍…...

Python基于YOLOv8和OpenCV实现车道线和车辆检测

使用YOLOv8&#xff08;You Only Look Once&#xff09;和OpenCV实现车道线和车辆检测&#xff0c;目标是创建一个可以检测道路上的车道并识别车辆的系统&#xff0c;并估计它们与摄像头的距离。该项目结合了计算机视觉技术和深度学习物体检测。 1、系统主要功能 车道检测&am…...

代码随想录算法训练营第六十天|KM94.城市间货物运输Ⅰ|KM95.城市间货物运输Ⅱ|KM96.城市间货物运输Ⅲ

94. 城市间货物运输 I 2、Bellman_ford队列优化算法&#xff08;又名SPFA&#xff09; SPFA是对Bellman_ford算法的优化&#xff0c;由于Bellman_ford 算法 每次都是对所有边进行松弛&#xff0c;其实是多做了一些无用功。其实只需要对 上一次松弛的时候更新过的节点作为出发节…...

人工智能学习路线全链路解析

一、基础准备阶段&#xff08;预计 2-3 个月&#xff09; &#xff08;一&#xff09;数学知识巩固与深化 线性代数&#xff08;约 1 个月&#xff09;&#xff1a; 矩阵基础&#xff1a;回顾矩阵的定义、表示方法、矩阵的基本运算&#xff08;加法、减法、乘法&#xff09;&…...

C++语言的学习路线

C语言的学习路线 C是一种强大的高级编程语言&#xff0c;广泛应用于系统软件、游戏开发、嵌入式系统和高性能应用等多个领域。由于其丰富的功能和灵活性&#xff0c;C是一门值得深入学习的语言。本文旨在为初学者制定一条系统的学习路线&#xff0c;帮助他们循序渐进地掌握C语…...

用于与多个数据库聊天的智能 SQL 代理问答和 RAG 系统(3) —— 基于 LangChain 框架的文档检索与问答功能以及RAG Tool的使用

介绍基于 LangChain 框架的文档检索与问答功能&#xff0c;目标是通过查询存储的向量数据库&#xff08;VectorDB&#xff09;&#xff0c;为用户的问题检索相关内容&#xff0c;并生成自然语言的答案。以下是代码逻辑的详细解析&#xff1a; 代码结构与功能 初始化环境与加载…...

20250110doker学习记录

1.本机创建tts环境。用conda. 0.1安装。我都用的默认&#xff0c;你也可以。我安装过一次&#xff0c;如果修复&#xff0c;后面加 -u bash Anaconda3-2024.10-1-Linux-x86_64.sh等待一会。 (base) ktkt4028:~/Downloads$ conda -V conda 24.9.2学习资源 Conda 常用命令大…...

MPU6050: 卡尔曼滤波, 低通滤波

对于MPU6050(一种集成了三轴加速度计和三轴陀螺仪的惯性测量单元),对加速度值进行卡尔曼滤波,而对角速度进行低通滤波的选择是基于这两种传感器数据的不同特性和应用需求。以下是详细解释: 加速度值与卡尔曼滤波 为什么使用卡尔曼滤波? 噪声抑制: 加速度计信号通常包含…...

C++的标准和C++的编译版本

C的标准和C的编译版本&#xff1a;原理和概念 理解 C标准 和 C编译版本 的关系是学习 C 的一个重要部分。这两者虽然看似相关&#xff0c;但实际上分别涉及了不同的概念和技术。下面将通过层次清晰的解释&#xff0c;帮助新手理解这两个概念的差异、特点及其相互关系。 一、C标…...

python学习笔记—17—数据容器之字符串

1. 字符串 (1) 字符串能通过下标索引来获取其中的元素 (2) 旧字符串无法修改特定下标的元素 (3) index——查找字符串中任意元素在整个字符串中的起始位置(单个字符或字符串都可以) tmp_str "supercarrydoinb" tmp_position1 tmp_str.index("s") tmp_p…...

UE5 使用内置组件进行网格切割

UE引擎非常强大&#xff0c;直接内置了网格切割功能并封装为蓝图节点&#xff0c;这项功能在UE4中就存在&#xff0c;并且无需使用Chaos等模块。那么就来学习下如何使用内置组件实现网格切割。 1.配置测试用StaticMesh 对于被切割的模型&#xff0c;需要配置一些参数。以UE5…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

深入理解Optional:处理空指针异常

1. 使用Optional处理可能为空的集合 在Java开发中&#xff0c;集合判空是一个常见但容易出错的场景。传统方式虽然可行&#xff0c;但存在一些潜在问题&#xff1a; // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

面试高频问题

文章目录 &#x1f680; 消息队列核心技术揭秘&#xff1a;从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"&#xff1f;性能背后的秘密1.1 顺序写入与零拷贝&#xff1a;性能的双引擎1.2 分区并行&#xff1a;数据的"八车道高速公路"1.3 页缓存与批量处理…...

在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例

目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码&#xff1a;冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...