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 ,程序运行时会报错(依赖外部库)。
相关推荐
Trouvaille ~9 分钟前
【Linux】TCP Socket编程实战(一):API详解与单连接Echo Server
linux·运维·服务器·网络·c++·tcp/ip·socket
旖旎夜光1 小时前
Linux(13)(中)
linux·网络
威迪斯特1 小时前
CentOS图形化操作界面:理论解析与实践指南
linux·运维·centos·组件·图形化·桌面·xserver
一方热衷.2 小时前
在线安装对应版本NVIDIA驱动
linux·运维·服务器
独自归家的兔2 小时前
ubuntu系统安装dbswitch教程 - 备份本地数据到远程服务器
linux·运维·ubuntu
ONE_SIX_MIX2 小时前
ubuntu 24.04 用rdp连接,桌面黑屏问题,解决
linux·运维·ubuntu
龙飞052 小时前
Systemd -systemctl - journalctl 速查表:服务管理 + 日志排障
linux·运维·前端·chrome·systemctl·journalctl
*小海豚*2 小时前
在linux服务器上DNS正常,但是java应用调用第三方解析域名报错
java·linux·服务器
June`2 小时前
muduo项目排查错误+测试
linux·c++·github·muduo网络库
消失的旧时光-19432 小时前
Linux 编辑器入门:nano 与 vim 的区别与选择指南
linux·运维·服务器