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

木下~Linux系统编程之静态库与动态库

一、核心概念与基础定义

1. 库的本质

库是预编译的功能代码集合文件,核心价值是实现代码复用、隐藏业务源码、缩减程序体积,分为静态库动态库两类,二者最核心的差异是代码加载时机不同

2. 分类与命名规范(Linux 环境)

类型核心加载逻辑文件名规范固定格式说明
静态库编译时,由编译器直接链接嵌入可执行程序libxxx.alib 为固定前缀,xxx 为自定义库名,.a 为静态库固定后缀
动态库(共享库)运行时,由操作系统按需动态加载到内存libxxx.solib 为固定前缀,xxx 为自定义库名,.so 为动态库固定后缀

3. 库的作用

  • 避免重复开发,大幅缩减业务代码量;
  • 封装后隐藏源码,仅暴露调用接口,功能效果与源码一致;
  • 静态库保障程序可移植性,动态库降低程序体积、提升迭代运维效率。

二、编译参数

参数核心作用
-I(大写 i)指定头文件(.h)的搜索路径
-L指定库文件(.a/.so)的搜索路径
-l(小写 L)指定链接的库名(需去掉前缀lib、后缀.a/.so
-o指定编译生成的目标文件名
-c仅编译源码生成.o 目标文件,不执行链接操作
-shared编译生成动态库的专属核心参数

三、静态库制作与使用全流程

1. 制作核心步骤

  1. 准备源码:功能函数的源文件(如 add.c、sub.c)和对应头文件(add.h、sub.h)
  2. 生成目标文件:将.c 源码编译为.o 目标文件
    gcc src/*.c -c -I inc
  3. 打包生成静态库:通过 ar 工具打包.o 文件
    ar -cr libxxx.a *.o # -c:创建库文件;-r:替换库中已有的目标文件
  4. 库文件部署:可自定义存放路径,无需提前放入系统目录。

2. 3 种使用方式 & 关键注意事项

使用方式标准编译命令核心注意事项
直接当作源文件使用gcc main.c libxxx.a -o m -I inc库文件必须放在.c 源文件之后,否则会报函数未定义引用
路径指定法(最常用)gcc main.c -o m -L ./lib -l xxx -I inc-L 指定库文件所在目录,-l 指定库名(需去掉 lib 前缀和.a 后缀)
系统默认路径法gcc main.c -o m -l xxx -I inc需将 libxxx.a 放入系统默认库路径(/lib、/usr/lib),无需指定 - L 参数

四、动态库制作与使用全流程

1. 制作核心步骤

  1. 准备源码:功能函数的源文件和对应头文件
  2. 生成目标文件:将.c 源码编译为.o 目标文件(与静态库一致)
    gcc src/*.c -c -I inc
  3. 编译生成动态库:通过 - shared 参数生成.so 文件
    gcc -shared -o libxxx.so *.o
  4. 库文件部署:必须将.so 文件放入系统默认库路径(/lib、/usr/lib),否则编译无报错,但运行时会报找不到共享库文件。

2. 2 种使用方式 & 关键注意事项

使用方式标准编译命令核心注意事项
直接当作源文件使用gcc main.c libxxx.so -o mm -I inc必须提前将 libxxx.so 拷贝到系统默认库路径,否则运行报错
标准路径指定法(常用)gcc main.c -o mm -I inc -L ./lib -l xxx-L 仅指定编译时库路径,运行时仍依赖系统默认库路径中的.so 文件

五、静态库 vs 动态库 对比

对比维度静态库动态库
加载时机编译时完整嵌入可执行程序程序运行时由系统动态加载
可执行文件体积大,包含完整的库代码小,仅保留接口引用
程序可移植性强,单文件可独立运行,无额外依赖弱,必须同步携带依赖的.so 文件,并部署到目标设备系统库路径
升级与维护繁琐,库修改后必须重新编译整个程序便捷,仅需替换.so 文件,无需重新编译主程序
内存占用多程序调用同个库,内存中存在多份副本多程序调用同个库,内存中仅存一份共享副本,节省系统内存
运行速度更快,无运行时加载开销略慢,存在运行时动态加载开销
http://www.jsqmd.com/news/457782/

相关文章:

  • 多无人机动态避障路径规划研究:基于粒子群优化算法PSO的多无人机动态避障路径规划研究(可以自定义无人机数量及起始点),MATLAB代码
  • 落叶清扫机设计(开题报告+三维图)
  • 基于大数据+Hadoop+深度学习的股票预测系统设计与开发(源码+精品论文+答辩PPT等资料)
  • 基于springboot中小学数字化教学资源管理平台(源码+文档+调试+讲解)
  • 从智能马桶到淋浴房,九牧凭什么持续领跑行业
  • C++核心概念:命名空间与构造析构解析
  • 三进制+钱学森:复杂系统动态平衡的底层同频与工程化实现原则
  • Android Intent.setAction失效报错排查与修复全方案
  • 万字长文实测:对比5款主流论文AI,为何 Scholingo 是最懂中国高校的“降重神器”?
  • 并发编程笔记1
  • 青蛙跳台阶
  • Linux系统编程-数据库-SQLite
  • Flutter —— GetIt、Dio
  • 基于springboot的人事管理系统(源码+文档+调试+讲解)
  • C语言二维数组详解:定义与初始化
  • Claw 批量生成公众号文章实践:一天写 100 篇的工作流复盘
  • 基于大数据+Hadoop+深度学习的酒店评论文本情感分析研究设计与开发(源码+精品论文+答辩PPT等资料)
  • 4个关键步骤解决ComfyUI ControlNet Aux模型下载难题:开源工具配置优化指南
  • 阿姆智创15.6寸工控触摸一体机,赋能工业自动化的硬核终端,源头工厂支持ODM定制
  • 保姆级windows+WSL2(非C盘安装)部署OpenClaw
  • 【问题解决】| 【黑马点评】 | 虚拟机IP总是变动,如何修改成固定IP
  • 影音杂乱?远程看片难?Plex+cpolar 打造随身私人影院,解决所有难题
  • 【算法】约数个数、约数和
  • 【保姆级教程】Windows系统下使用国内阿里云大模型接入Claude Code
  • python中交互式和文件式的运行
  • P2并联混动仿真模型:探索未来汽车的动力与经济性
  • [HC04-Arduino]——光电探测器
  • 消息队列(MQ)入门必知必会五大基础概念:异步,削峰,解耦,生产者,消费者详细解读 一篇搞懂 超强类比
  • 11b. OpenAI API密钥获取指南
  • Serverless冷启动性能优化:从Firecracker微虚拟机隔离到代码预热算法的深度实践