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 小时前
Ubuntu 20.04安装CUDA 11.8
linux·运维·ubuntu
梁洪飞17 小时前
clk学习
linux·arm开发·嵌入式硬件·arm
~光~~17 小时前
【嵌入式linux驱动——点亮led】基于鲁班猫4 rk3588s
linux·点灯·嵌入式linux驱动
yuanmenghao18 小时前
车载Linux 系统问题定位方法论与实战系列 - 车载 Linux 平台问题定位规范
linux·运维·服务器·网络·c++
qq_5895681019 小时前
centos6.8镜像源yum install不成功,无法通过镜像源下载的解决方式
linux·运维·centos
weixin_5160230719 小时前
linux下fcitx5拼音的安装
linux·运维·服务器
hunter145020 小时前
Linux 进程与计划任务
linux·运维·服务器
楼田莉子20 小时前
Linux学习之磁盘与Ext系列文件
linux·运维·服务器·c语言·学习
陌上花开缓缓归以20 小时前
linux 怎么模拟系统panic重启
linux·运维·服务器
KL's pig/猪头/爱心/猪头21 小时前
写一个rv1106的led驱动3-功能函数编写
linux·驱动开发·rv1106