GCC 指令详解及动态库、静态库的使用( 四 )


add.c
#include <stdio.h>int add(int a, int b){return a + b;}sub.c
#include <stdio.h>int subtract(int a, int b){return a - b;}mult.c
#include <stdio.h>int multiply(int a, int b){return a * b;}具体操作步骤如下:
# 第一步:将源文件 add.c、sub.c、mult.c 进行汇编,得到二进制目标文件 add.o、sub.o、mult.o$ gcc -c add.c sub.c mult.c# 第二步:将生成的目标文件通过 ar 工具打包生成静态库$ ar rcs libcalc.a add.o sub.o mult.o2.2.4 静态库的使用定义 main 函数如下所示:
main.c
#include <stdio.h>int main(){int a = 20;int b = 12;printf("a = %d, b = %d\n", a, b);printf("a + b = %d\n", add(a, b));printf("a - b = %d\n", subtract(a, b));printf("a * b = %d\n", multiply(a, b));return 0;}并将静态库 libcalc.a 置于同级目录下:

GCC 指令详解及动态库、静态库的使用

文章插图
通过指令$ gcc main.c -o main -L ./ -l calc编译 main.c 文件,并链接静态库 libcalc.a:
  • -L:指定使用的库的路径(因为在同一级目录下,所以可以直接用了./,或者使用绝对路径也是可以的)
  • -l:指定使用的库(库的名字一定要掐头去尾 。如:libcalc.a 变为 calc)
编译结果会提示三个 warning,这是由于没有定义这些函数导致的,先暂时不用管 。
运行 main 结果如下:
GCC 指令详解及动态库、静态库的使用

文章插图
我们思考这么一个问题:由于静态库是我们自己制作的,其所包含的函数我们很清楚,直接链接并使用即可 。但如果别人想要使用呢?他们可不清楚静态库中的函数该如何调用,所以我们有必要提供一个头文件,这样将静态库及头文件交给其他人时,他们知道该如何用了 。
head.h
#ifndef _HEAD_H_#define _HEAD_H_int add(int a, int b);int subtract(int a, int b);int multiply(int a, int b);#endif还记得之前的报错吗?现在有了头文件就要使用起来 。
main.c
#include <stdio.h>#include "head.h"int main(){int a = 20;int b = 12;printf("a = %d, b = %d\n", a, b);printf("a + b = %d\n", add(a, b));printf("a - b = %d\n", subtract(a, b));printf("a * b = %d\n", multiply(a, b));return 0;}编译、链接、运行,一气呵成:
GCC 指令详解及动态库、静态库的使用

文章插图
2.2.5 ar 命令参数介绍制作静态库时所使用的指令$ ar rcs libcalc.a add.o sub.o mult.o div.o共有三个参数:
  • -c:创建一个库,不管库是否存在,都将创建 。这个很好理解,就不做过多的解释了 。
  • -r:在库中插入(替换)模块。默认新的成员添加在库的结尾处,如果模块名已经在库中存在,则替换同名的模块 。
  • -s:创建目标文件索引,这在创建较大的库时能加快时间 。
参数 -r 的详细解释
假设现在有了新的需求,需要静态库 libcalc.a 提供除法运算的功能模块,该怎么操作呢?
首先我们需要新建一个除法运算的源文件 div.c:
#include <stdio.h>double divide(int a, int b){return (double)a / b;}并通过汇编操作生成目标文件 div.o 。
接下来我们可以通过 -r 参数将除法运算的模块添加到静态库中:$ ar -r libcalc.a div.o
并且要在 head.h 中增加对除法运算的声明:
#ifndef _HEAD_H_#define _HEAD_H_// Otherdouble divide(int a, int b);#endif参数 -s 的详细解释
在获取一个静态库的时候,我们可以通过$ nm -s libcalc.a来显示库文件中的索引表:

经验总结扩展阅读