UNIXC01 库文件, 静态库的制作和使用

库文件基础

  • 什么是函数库?
    • 存放函数的仓库就是函数库
    • 系统提供了标准库和一些其他的库文件
    • 用户也可以自定义函数库
  • 根据链接方式的不同, 将函数库分为动态库(共享库)和静态库两种
  • 库函数的命名规则
    • 动态库命名规则 lib库名.so
    • 静态库命名规则 lib库名.a

静态库的制作和使用

  • 1. 将所有要加入库中的源文件编译为目标文件(gcc -c *.c)

  • 2. 将第一步生成的所有目标文件打包为静态库文件(ar -r lib库名.a *.o )

  • 3. 使用静态库文件链接生成可执行文件(gcc main.o -L库的路径 -l库名)

  • 使用静态库生成可执行文件, 静态链接的原理

  • #include <> 和 “” 的区别

    • 系统路径PATH和当前路径

p_math.h (定义各个模块间的接口)

// 如果没有定义了这个宏, 就定义这个宏,紧接着进行函数声明, 最后endif. 如果定义过, 就直接跳到endif
#ifndef P_MATH_H_ //为了避免头文件重复包含
#define P_MATH_H_ 
//函数声明
int t_add(int, int);
int t_sub(int, int);
int t_mul(int, int);
int t_div(int, int);

#endif

add.c (加法模块)

#include "p_math.h"
int t_add(int x, int y){
    return x + y;
}
int t_sub(int x, int y){
    return x - y;
}

mul.c (乘法模块)

#include "p_math.h"
int t_mul(int x, int y) {
    return x * y;
}

int t_div(int x, int y) {
    return x / y;
}

main.c

#include "p_math.h"
#include <stdio.h>

int main(void){
    int val_x = 6, val_y = 2;
    printf("%d + %d = %d\n", val_x, val_y, t_add(val_x, val_y));
    printf("%d * %d = %d\n", val_x, val_y, t_mul(val_x, val_y));
}
# 1. 源文件编译为目标文件 
$ gcc -c add.c mul.c main.c
# 2.将 目标文件打包为静态库文件 libpmath.a, 生成库名叫做pmath的静态库
$ ar -r libpmath.a add.o mul.o 
ar: creating libpmath.a
#看下这个库里有啥
$ ar -t libpmath.a  
add.o
mul.o
# 3. 使用静态库文件链接生成可执行文件
# -L后接路径, -l后接路径下的库名 pmath
$ gcc main.o -L. -lpmath
$ ./a.out 
6 + 2 = 8
6 * 2 = 12

$ nm libpmath.a 

add.o:
0000000000000000 T t_add
0000000000000014 T t_sub

mul.o:
0000000000000013 T t_div
0000000000000000 T t_mul

# 将main.c 中的 t_mul 所在语句注释掉
$ gcc -c add.c mul.c main.c
$ gcc *.o
# 多个目标文件链接, 会把多个模块的内容都放一块得到可执行文件
$ nm a.out
....
0000000000400430 T _start
0000000000400526 T t_add
00000000004005a4 T t_div
0000000000601038 D __TMC_END__
0000000000400591 T t_mul
000000000040053a T t_sub
....
# 但静态库就不一样了, 用到那个就把哪个链接进来
$ gcc main.o -L. -lpmath
# 因为main.c中只用到add.o模块里的内容, 所以只把add.o里的内容链接进来了
# 链接进来以后 a.out 就是一个独立的可执行程序, 不在依赖静态库
$ nm a.out
....
0000000000400430 T _start
000000000040056b T t_add
0000000000601038 D __TMC_END__
000000000040057f T t_sub
....
$ rm libpmath.a
$ a.out
6+2=8

除了静态库编译, 还有之前两种编译方式,回顾

# 之前的两种生成可执行文件的方法
# 1.
$ gcc *.c #编译链接一步到胃(开个小车)
$ ./a.out 
6 + 2 = 8
6 * 2 = 12

# 2.
$ gcc -c *.c #编译生成目标文件
$ gcc *.o	#链接目标文件成可执行文件
$ ./a.out 
6 + 2 = 8
6 * 2 = 12

静态库的缺点

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值