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

如果再来一个用户 C 呢?有没有感觉很麻烦的样子?那么我们完全可以这样做:
#include <stdio.h>int main(){#ifdef CHARGE//付费用户执行流程printf("该用户已付费,执行付费功\n");#else//白嫖用户执行流程printf("白嫖用户,拒绝执行付费功能\n");#endifprintf("公共功能\n");return 0;}在编译付费用户的时候,添加 -D CHARGE 参数;编译白嫖用户 , 则不添加 。这样的话,不管来多少用户,都只需要维护一个分支即可 。
1.4.2 指定 C 方言(-std)对于如下 C 语言代码:
#include <stdio.h>int main(){for (int i = 1; i <= 3; i++){printf("i = %d\n", i);}return 0;}在编译时是会报错的:

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

文章插图
但如果我们加上 -std=c99,就可以了:
GCC 指令详解及动态库、静态库的使用

文章插图
二、静态库和动态库2.1 扫盲库是「已经写好的、供使用的」可复用代码,每个程序都要依赖很多基础的底层库 。
从本质上,库是一种可执行代码的二进制形式,可以被操作系统载入内存执行 。程序中调用的库有两种「静态库和动态库」,所谓的「静态、动态」指的是链接的过程 。
2.2 静态库2.2.1 静态库简介在 Linux 中静态库以 lib 作为前缀、以 .a 作为后缀,形如 libxxx.a(其中的 xxx 是库的名字,自己指定即可) 。静态库以之所以称之为「静态库」,是因为在链接阶段 , 会将汇编生成的目标文件 .o 与引用的库一起链接到可执行文件中,对应的链接方式称为静态链接 。
2.2.2 静态库的生成在 Linux 中静态库由程序 ar 生成 。生成静态库,需要先对源文件进行汇编操作得到二进制格式的目标文件(以 .o 结尾的文件),然后再通过 ar 工具将目标文件打包就可以得到静态库文件了 。
GCC 指令详解及动态库、静态库的使用

文章插图
使用 ar 工具创建静态库的一般格式为$ ar -rcs libxxx.a 若干原材料(.o文件)
2.2.3 静态库的制作举例在某目录中有如下源文件,用来实现一个简单的计算器 。
【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;}

推荐阅读