Linux动静态库与动静态链接

在Linux开发中,库是预编译的代码集合,供程序调用;链接则是将库代码与程序代码结合的过程。根据库的存储和链接方式,分为静态库( .a )和动态库( .so ),对应的链接方式为静态链接和动态链接。

一、基本概念
  1. 静态库(Static Library)
  • 以 .a 为后缀,是目标文件( .o )的归档包。
  • 静态链接:编译时,链接器会将静态库中被程序调用的代码完整复制到可执行文件中。
  • 特点:可执行文件独立运行,不依赖外部库;文件体积大;库更新后,程序需重新编译链接。
  1. 动态库(Shared Library)
  • 以 .so 为后缀(Shared Object),是可被多个程序共享的代码库。
  • 动态链接:编译时,链接器仅记录程序对动态库的引用(如库名、函数地址),不复制库代码;程序运行时,由动态链接器加载动态库到内存并完成链接。
  • 特点:可执行文件体积小;多个程序共享同一份动态库,节省内存;库更新后,无需重新编译程序(只要接口兼容)。
二、代码示例(C语言)

准备工作:编写库的源文件

创建两个文件, math.c (库实现)和 math.h (库头文件):

c 复制代码
  
// math.h 头文件
#ifndef MATH_H
#define MATH_H
int add(int a, int b);
int sub(int a, int b);
#endif
 
 
c
  
// math.c 库实现
#include "math.h"
int add(int a, int b) {
    return a + b;
}
int sub(int a, int b) {
    return a - b;
}
 
  1. 制作并使用静态库

步骤1:编译生成目标文件 .o

c 复制代码
bash
  
gcc -c math.c -o math.o  # -c 表示只编译不链接,生成目标文件
 

步骤2:打包生成静态库 .a

c 复制代码
bash
 
ar rcs libmath.a math.o  # ar是归档工具,rcs:创建、替换、索引

步骤3:编写主程序并静态链接

创建主程序 main.c :

c 复制代码
  
#include <stdio.h>
#include "math.h"
int main() {
    printf("3+2=%d\n", add(3, 2));
    printf("3-2=%d\n", sub(3, 2));
    return 0;
}
 

步骤4:编译主程序并链接静态库

c 复制代码
bash
 
gcc main.c -o main_static -L. -lmath  # -L. 指定库路径(当前目录),-lmath 链接libmath.a

步骤5:运行与验证

c 复制代码
bash
  
./main_static
 

输出:

plaintext

3+2=5

3-2=1

  • 验证静态链接:删除静态库 libmath.a ,程序仍可正常运行(代码已复制到可执行文件中)。
  1. 制作并使用动态库

步骤1:编译生成位置无关的目标文件 .o

c 复制代码
bash
  
gcc -c -fPIC math.c -o math.o  # -fPIC 生成位置无关代码,用于动态库
 

步骤2:生成动态库 .so

c 复制代码
bash
  
gcc -shared -o libmath.so math.o  # -shared 表示生成动态库
 

步骤3:编译主程序并动态链接

c 复制代码
bash
 
gcc main.c -o main_dynamic -L. -lmath  # 编译命令与静态链接一致,链接器自动优先找动态库

步骤4:运行与验证

直接运行可能报错(系统找不到动态库),需指定动态库路径:

bash

方式1:临时指定环境变量

export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH

./main_dynamic

方式2:将动态库复制到系统库路径(如/usr/lib)

cp libmath.so /usr/lib

./main_dynamic

输出与静态链接一致:

plaintext

3+2=5

3-2=1

  • 验证动态链接:删除动态库 libmath.so ,程序运行时会报错(依赖外部库)。
相关推荐
有谁看见我的剑了?16 分钟前
linux 添加硬盘后系统识别不到硬盘处理
linux·运维·服务器
yc_12242 小时前
用 Visual Studio 远程调试 Linux:从零到流畅的完整指南
linux·ide·visual studio
计算机安禾2 小时前
【Linux从入门到精通】第31篇:防火墙漫谈——iptables与firewalld防护指南
linux·运维·php
下一页盛夏花开2 小时前
ubuntu 20中安装QT以后出现红色空心断点
linux·运维·ubuntu
sanshanjianke3 小时前
Thunderobot 911ME 笔记本 Linux 风扇控制研究
linux
fengyehongWorld6 小时前
TeraTerm ttl脚本登录wsl
linux·teraterm
乌托邦的逃亡者6 小时前
Linux中如何检测IP冲突
linux·运维·tcp/ip
一曦的后花园6 小时前
linux搭建promethes并对接node-exporter指标
linux·运维·服务器
乌托邦的逃亡者7 小时前
CentOS/Openeuler主机中,为一个网卡设置多个IP地址
linux·运维·网络·tcp/ip·centos
念恒123068 小时前
进程控制---自定义Shell
linux·c语言