当前位置: 首页 > 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…...

51单片机——串口通信(重点)

1、通信 通信的方式可以分为多种&#xff0c;按照数据传送方式可分为串行通信和并行通信&#xff1b; 按照通信的数据同步方式&#xff0c;可分为异步通信和同步通信&#xff1b; 按照数据的传输方向又可分为单工、半双工和全双工通信 1.1 通信速率 衡量通信性能的一个非常…...

Taro+Vue实现图片裁剪组件

cropper-image-taro-vue3 组件库 介绍 cropper-image-taro-vue3 是一个基于 Vue 3 和 Taro 开发的裁剪工具组件&#xff0c;支持图片裁剪、裁剪框拖动、缩放和输出裁剪后的图片。该组件适用于 Vue 3 和 Taro 环境&#xff0c;可以在网页、小程序等平台中使用。 源码 https:…...

PHP民宿酒店预订系统小程序源码

&#x1f3e1;民宿酒店预订系统 基于ThinkPHPuniappuView框架精心构建的多门店民宿酒店预订管理系统&#xff0c;能够迅速为您搭建起专属的、功能全面且操作便捷的民宿酒店预订小程序。 该系统不仅涵盖了预订、退房、WIFI连接、用户反馈、周边信息展示等核心功能&#xff0c;更…...

Hadoop3.x 万字解析,从入门到剖析源码

&#x1f496; 欢迎来到我的博客&#xff01; 非常高兴能在这里与您相遇。在这里&#xff0c;您不仅能获得有趣的技术分享&#xff0c;还能感受到轻松愉快的氛围。无论您是编程新手&#xff0c;还是资深开发者&#xff0c;都能在这里找到属于您的知识宝藏&#xff0c;学习和成长…...

VUE3 常用的组件介绍

Vue 组件简介 Vue 组件是构建 Vue 应用程序的核心部分&#xff0c;组件帮助我们将 UI 分解为独立的、可复用的块&#xff0c;每个组件都有自己的状态和行为。Vue 组件通常由模板、脚本和样式组成。组件的脚本部分包含了各种配置选项&#xff0c;用于定义组件的逻辑和功能。 组…...

deepin-Wine 运行器合并打包器和添加从镜像提取 DLL 的功能

Wine 运行器是一个图形化工具&#xff0c;旨在简化 Wine 环境的管理和使用。它不仅提供了运行和管理 Wine 容器的功能&#xff0c;还增加了打包器和从镜像提取 DLL 的功能。以下是该工具的详细介绍和使用方法。 一、工具概述 Wine 运行器是一个使用 Python3 的 tkinter 构建的图…...

[大模型]本地离线运行openwebui+ollama容器化部署

本地离线运行Openweb-ui ollama容器化部署 说明安装internet操作内网操作问题线程启动错误最终命令总结说明 最近公司有一个在内网部署一个离线大模型的需求,网络是离线状态,服务器有A100GPU,一开始是想折腾开源chatGML4大模型,因为使用过gml3,所以想着部署gml4应该不难。…...

再次梳理ISP的大致流程

前言&#xff1a; 随着智能手机的普及&#xff0c;相机与我们的生活越来越紧密相关。在日常生活中&#xff0c;我们只需要轻轻按下手机上的拍照按钮&#xff0c;就能记录下美好时刻。那么问题来了&#xff1a;从我们指尖按下拍照按钮到一张色彩丰富的照片呈现在我们面前&#x…...

HBuilderX打包ios保姆式教程

1、登录苹果开发者后台并登录已认证开发者账号ID Sign In - Apple 2、创建标识符&#xff08;App ID&#xff09;、证书&#xff0c;描述文件 3、首先创建标识符&#xff0c;用于新建App应用 3-1、App的话直接选择第一个App IDs&#xff0c;点击右上角继续 3-2、选择App&#x…...

《解锁鸿蒙系统AI能力,开启智能应用开发新时代》

在当今科技飞速发展的时代&#xff0c;鸿蒙系统以其独特的分布式架构和强大的AI能力&#xff0c;为开发者们带来了前所未有的机遇。本文将深入探讨开发者如何利用鸿蒙系统的AI能力开发更智能的应用&#xff0c;开启智能应用开发的新时代。 鸿蒙系统构筑了15系统级的AI能力&…...

网站建设策划书ppt/百度客服24小时人工服务在线咨询

http://www.oschina.net/question/12_50469 Netcat 或者叫 nc 是 Linux 下的一个用于调试和检查网络工具包。可用于创建 TCP/IP 连接&#xff0c;最大的用途就是用来处理 TCP/UDP 套接字。 这里我们将通过一些实例来学习 netcat 命令。 1. 在服务器-客户端架构上使用 Netcat …...

ps怎么做网站首页和超链接/软文推广广告公司

解决Eclipse删除Tomcat8后无法新增问题参考文章&#xff1a; &#xff08;1&#xff09;解决Eclipse删除Tomcat8后无法新增问题 &#xff08;2&#xff09;https://www.cnblogs.com/chiying/p/5642657.html 备忘一下。...

广州推广型网站建设/制作网页的流程步骤

路由器之家网今天精心准备的是《在线闪字》&#xff0c;下面是详解&#xff01;闪字在线制作有没有那种一笔一笔写出来的闪字&#xff1f;或者能制作很可爱很温暖闪字的网站&#xff1f;很急啊&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;...有没…...

wordpress添加富强民主/网络热词缩写

首先根据你的问题&#xff0c;先实际运行一下代码&#xff0c;如下&#xff1a;通过代码结果&#xff0c;我们看到两者都是True&#xff0c;所以是相等的为什么相等呢&#xff1f;此处涉及到运算优先级的问题1、首先比较容易理解的是当x是空字符串&#xff0c;也就是什么都没有…...

工业设计是冷门专业吗/seo推广百度百科

1. font-face是什么? CSS3中的一个模块, 使用它, 我们可以在web应用中使用自己喜欢的字体.2. 基本使用方法 font-face {font-family: yourWebFontName; // 自定义的字体名称src: url(../**/**) format(truetype); // url(...)字体路径 format()见下font-weight:…...

做谷歌网站使用什么统计代码/网站推广公司大家好

导读&#xff1a;本文主要介绍 CentOS 系统二进制安装 MySQL 5.7.23 版本的安装步骤&#xff0c;其他版本安装过程相似。1.前置准备卸载旧版MySQL查看rpm包rpm -qa|grep mysql 若有可用rpm -e卸载查找mysql残留包&#xff0c;有则删除&#xff0c;没有则忽略find / -name mysql…...