news 2026/1/30 3:25:47

静态库与动态库

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
静态库与动态库

文章目录

  • 静态库
    • 特点
    • 创建
      • ar 命令参数
    • 链接静态库
  • 动态库
    • 特点
    • 创建
    • 链接动态库(共享库)
      • 常见错误
  • 静态库与动态库(共享库)的区别
  • 查看库中相关信息

  • 库是一个二进制文件,包含的代码可被程序调用
  • 常见的有:标准C库、数学库、线程库……
  • 库是事先编译好的,可以复用的代码
  • 库的源码,可从对应的官网下载后编译,也可以直接安装二进制包
  • 在OS上运行的程序基本上都要使用库,例如linux系统的库路径:/lib /usr/lib
  • 使用库可以提高开发效率
  • Linux下包含静态库和共享库,Windows和Linux下库文件的格式不兼容

静态库

特点

  • 优势:
    • 编译(链接)时把静态库中相关代码复制到可执行文件中,运行时不再需要加载静态库,优化运行过程;
    • 程序运行时无需等待,调用接口更快,优化运行速度
  • 不足:
    • 占用更多磁盘和内存空间
    • 如静态库升级,程序也需要重新编译链接库,维护不易

创建

  • 第一步:明确库中函数的功能、返回值、参数含义
  • 第二步:编写库源码,例如hello
voidhello(void){printf("hello world\n");}
  • 第三步:编译生成目标文件.o
    • gcc -c hello.c -o hello.o -Wall
  • 第四步:创建静态库 hello
    • ar -rsv libhello.a hello.o

静态库名字要以lib开头,后缀名为.a

没有main函数的.c 文件不能直接生成可执行文件

ar 命令参数

  • c禁止在创建库时产生的正常消息
  • r如果指定的文件已经存在于库中,则替换它
  • s无论 ar 命令是否修改了库内容都强制重新生成库符号表
  • v将建立新库的详细的逐个文件的描述写至标准输出
  • q将指定的文件添加到库的末尾
  • t将库的目录写至标准输出

链接静态库

  • 第一步:编写应用程序test.c
#include<stdio.h>voidhello(void);intmain(intargc,constchar*argv[]){//调用库函数hello();return0;}
  • 第二步:编译test.c 并链接静态库libhello.a
    • gcc -o 目标文件 源码.c -L路径 -lxxxx
      • -L 表示库所在的路径
      • -l 后面跟库的名称
      • -I 指定头文件所在路径
    • eg:gcc -o test test.c -L. -lhello

动态库

特点

  • Linux 动态库,也称为共享库,是一种在运行时由可执行文件动态链接和加载的代码库
  • 其主要特点包括:
    • 代码共享:多个程序可以共享同一个动态库,从而节省内存和磁盘空间
    • 更新无需重新编译:动态库更新后,只需要更新库文件即可,不需要重新编译使用它的程序
    • 版本控制:可以同时存在多个版本的动态库,程序可以选择使用哪个版本
    • 扩展功能:动态库可以用于扩展程序的功能,无需修改程序代码

创建

  • 第一步:明确库中函数的功能、返回值、参数含义
  • 第二步:编写库源码,例如hello.c
#include<stdio.h>voidhello(void){printf("hello world\n");}
  • 第三步:编译生成位置无关代码的目标文件.o
    • gcc -fPIC -c hello.c -o hello.o
  • 第四步:生成动态库(共享库)
    • $ gcc -shared hello.o -o libhello.so

链接动态库(共享库)

  • 第一步:编写应用程序test.c
#include<stdio.h>voidhello(void);intmain(intargc,constchar*argv[]){//调用库函数hello();return0;}
  • 第二步:链接动态库(共享库),编译可执行文件
    • gcc -o 目标文件 源码.c -L路径 -l共享库名
      • -L 表示库所在的路径
      • -l 后面跟库的名称

常见错误

  • 执行调用了动态库的可执行文件,出现错误:

./main: error while loading shared libraries: libhello.so: cannot open sharedobject file: No such file or directory

- 含义:可执行文件所使用的动态库找不到
  • 解决办法一:
    • 找到动态库,拷贝一份到/usr/lib路径里面
    • $ sudo cp libhello.so /usr/lib/
  • 解决办法二:
    • 在 ~/.bashrc 文件里面添加语句:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:你的动态库的绝对路径
    • 使用 source ~/.bashrc 命令保存生效

静态库与动态库(共享库)的区别

  • Linux静态库与动态库(共享库)的主要区别包括文件后缀、链接方式、代码载入时间、生成的可执行文件大小、内存占用、更新与维护以及使用场景和优势等方面
  • 文件后缀与命名规则:
    • 静态库:后缀为“.a”,命名格式通常为“lib+库名称+.a”
    • 动态库:后缀为“.so”,命名格式通常为“lib+库名称+.so”
  • 链接方式与代码载入时间:
    • 静态库:在程序编译时,静态库的代码会被链接到目标代码中。因此,程序运行时将不再需要该静态库。链接过程在编译时期完成,执行时代码加载速度快
    • 动态库:在程序编译时,动态库的代码并不会被链接到目标代码中。而是在程序运行时,当需要用到动态库中的函数或类时,才将其载入内存。链接过程推迟到了运行时运行
  • 生成的可执行文件大小与内存占用:
    • 静态库:由于整个函数库的所有数据都会被整合进可执行程序中,因此生成的可执行文件通常比较大。这会导致计算机内存和磁盘的空间浪费
    • 动态库:程序在运行时执行到相关函数时才调用动态库中的相应函数,因此生成的可执行文件比较小。多个程序可以共享同一个动态库的代码,内存中只需存在一份动态库的实例,从而节省了内存空间
  • 更新与维护:
    • 静态库:如果静态库发生更改,所有使用它的程序都需要重新编译。这使得程序的更新和发布相对不便
    • 动态库:动态库的更改不会影响已经编译的程序。只需更新动态库文件,而无需重新编译程序。这使得程序的升级和维护更加简单
  • 使用场景与优势:
    • 静态库:适用于需要确保程序在所有环境中都能独立运行且不需要依赖外部库文件的场景。由于所有使用的函数都已经被编译进程序中,因此程序的运行更加稳定可靠。
    • 动态库:适用于需要节省内存和磁盘空间的场景,以及需要频繁更新库文件的场景。动态库使得多个程序可以共享同一个库文件,提高了资源的利用率。同时,动态库的升级也更加方便,只需更新库文件即可

查看库中相关信息

  • 在Linux中,nm 命令用于显示二进制文件(如可执行文件或库)的符号表
  • 通过nm命令观察库的功能与逻辑,可以应用在调试环节中
  • 当看到结果中出现T和U这样的字符时,它们代表了不同类型的符号
    • T:表示一个全局文本(代码)符号。在ELF(Executable and Linkable Format)格式的对象文件中,T通常意味着该符号是一个函数或变量,它在目标文件中定义(即它是可执行文件的一部分)
    • U:这表示一个未定义的符号。在链接阶段,如果一个符号被引用但未在链接的任何对象文件中定义,那么该符号会被标记为U。这通常意味着该符号是在其他库中定义的,或者在链接时需要通过某种方式(如链接器脚本或命令行参数)来指定其定义位置
  • nm libhello.a
hello.o: 0000000 T hello U puts
  • 静态库

  • 动态库

  • 查看可执行文件使用的动态库
    • <font style="color:rgb(51,51,51);">ldd 可执行文件</font>
root@haas-virtual-machine:/mnt/hgfs/share/newIOP# ldd testlinux-vdso.so.1=>(0x00007fff6548d000)libmyheby.so=>/mnt/hgfs/share/newIOP/day5/libmyheby.so(0x00007f5c89521000)libc.so.6=>/lib/x86_64-linux-gnu/libc.so.6(0x00007f5c89144000)/lib64/ld-linux-x86-64.so.2(0x000055fe52211000)
  • readelf 库名读取库信息
  • objdump -d 库名反汇编命令,实现显示可执行部分的汇编内容
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/29 14:25:17

卷积神经网络性能瓶颈突破:使用CUDA加速卷积运算

卷积神经网络性能瓶颈突破&#xff1a;使用CUDA加速卷积运算 在当今AI研发的日常中&#xff0c;一个再熟悉不过的场景是&#xff1a;你精心设计了一个卷积神经网络&#xff0c;在 CIFAR-10 上跑通了训练流程&#xff0c;信心满满地准备扩展到 ImageNet 或自定义的大规模图像数据…

作者头像 李华
网站建设 2026/1/26 7:09:56

YOLO目标检测支持HTTPS?SSL卸载+GPU加速

YOLO目标检测支持HTTPS&#xff1f;SSL卸载GPU加速 在智能制造车间的边缘服务器上&#xff0c;一台搭载Tesla T4的工控机正以每秒200帧的速度处理来自10路高清摄像头的视频流——这些画面中隐藏着微米级的电路板缺陷。与此同时&#xff0c;外部系统通过加密的HTTPS接口持续提交…

作者头像 李华
网站建设 2026/1/28 11:51:37

一篇爆款技术文带来的流量:如何引导用户购买GPU算力

一篇爆款技术文带来的流量&#xff1a;如何引导用户购买GPU算力 在AI模型训练动辄需要几十小时的今天&#xff0c;一个开发者最怕什么&#xff1f;不是代码写错&#xff0c;也不是数据不足——而是环境配了三天三夜还是跑不起来。明明装好了PyTorch&#xff0c;torch.cuda.is_a…

作者头像 李华
网站建设 2026/1/23 22:56:41

YOLO目标检测模型版本回滚机制:应对上线故障

YOLO目标检测模型版本回滚机制&#xff1a;应对上线故障 在智能制造工厂的质检线上&#xff0c;一台搭载YOLOv9的视觉检测系统突然开始频繁漏检微小缺陷——原本稳定的mAP指标从0.82骤降至0.63。仅仅15分钟后&#xff0c;运维平台自动触发了版本回滚流程&#xff0c;3分钟内服务…

作者头像 李华
网站建设 2026/1/28 2:18:24

复习——网络测试工具

网络测试工具一、常用网络测试工具详解1. telnet - 远程登录测试# 测试端口连通性 telnet 192.168.1.1 8888 telnet www.example.com 80# 如果没有指定端口&#xff0c;默认使用23端口&#xff08;远程登录&#xff09;作用&#xff1a;测试TCP端口是否开放&#xff0c;验证服务…

作者头像 李华