动静态库

库(Library)本质上是一组预先编译好的函数、类或变量的集合,它们可以被你的程序复用,而无需你重新编写这些代码。

静态库(Static Library)

  • 扩展名:在 Linux/Unix 中是 .a (Archive),在 Windows 中是 .lib
  • 优点:部署简单,程序独立,运行速度快
  • 缺点:体积大,多个程序共用时浪费空间,库更新需要重新编译整个程序

创建与使用(Linux示例)

mymath.h (头文件,声明函数)

#ifndef MYMATH_H
#define MYMATH_H

int add(int a, int b);
int subtract(int a, int b);

#endif

mymath.c (源文件,实现函数)

#include "mymath.h"

int add(int a, int b) 
{
    return a + b;
}

int subtract(int a, int b) 
{
    return a - b;
}

main.c

#include <stdio.h>
#include "mymath.h" // 包含我们的头文件

int main() 
{
    int a = 10, b = 5;
    printf("%d + %d = %d\n", a, b, add(a, b));
    printf("%d - %d = %d\n", a, b, subtract(a, b));
    return 0;
}
命令执行
#1.编译为目标文件 (.o) ,-c 选项表示只编译不链接。

gcc -c mymath.c -o mymath.o 

#2.创建静态库 (.a),使用 ar (archive) 命令将目标文件打包成库。

ar rcs libmymath.a mymath.o

#r:替换库中已有的文件或插入新文件。c:创建库(如果不存在)。s:创建索引,加快链接速度。


#3.使用静态库编译程序

gcc main.c -o main -L. -lmymath

#-L.:告诉编译器除了标准路径外,还在当前目录(.) 中寻找库文件。

#-lmymath:告诉编译器链接名为 mymath 的库。注意,编译器会自动添加 lib 前缀和 .a 后缀,所以我们只用写 -lmymath。

#4运行
./main
运行结果
10 + 5 = 15
10 - 5 = 5

此时,你可以删除 libmymath.a./main 依然可以运行,因为库代码已经复制到 main 可执行文件里了。

动态库(Shared Library / Dynamic Link Library)

  • 扩展名:在 Linux/Unix 中是 .so (Shared Object),在 Windows 中是 .dll

  • 优点:节省磁盘和内存空间(多个程序可共享),库更新无需重新编译主程序(接口兼容的前提下)
  • 缺点:部署稍复杂,需要确保运行环境有正确的库版本,略微增加运行时的开销

创建与使用(Linux示例)

使用相同的 mymath.hmymath.cmain.c 文件。

#1.编译为目标文件 (.o)
#编译时需要添加 -fPIC 选项,是动态库所必需的。

gcc -c -fPIC mymath.c -o mymath.o

#2创建动态库 (.so)
#-shared:告诉编译器生成一个动态库。

gcc -shared -o libmymath.so mymath.o

#3使用动态库编译程序

gcc main.c -o main_shared -L. -lmymath

#4运行

./main_shared

# 可能输出:./main_shared: error while loading shared libraries: libmymath.so: cannot open shared object file: No such file or directory
#原因:系统找不到 libmymath.so 文件。系统只在标准库路径(如 /lib, /usr/lib)和 LD_LIBRARY_PATH 环境变量指定的路径中查找动态库。

解决方法(选其一即可)

#临时方法(当前终端有效):
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./main_shared

#永久方法(拷贝到系统路径):
sudo cp libmymath.so /usr/lib
./main_shared 
# 重新打开终端可以正常运行了

总结

  • 使用静态库:当你希望程序独立分发,不想担心用户环境缺少依赖库时(例如,一些闭源商业软件)。或者对程序的启动速度有极致要求。

  • 使用动态库:这是更常见的选择。尤其是系统级的库(如 glibc)。当你的代码模块需要频繁更新时,动态库的优势非常明显。几乎所有 Linux 发行版都极力推荐使用动态库来节省空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值