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;}

推薦閱讀