mysql 靜態鏈結庫 靜態鏈結庫的建立和使用

2021-10-20 22:39:18 字數 4267 閱讀 4516

通過《gcc使用靜態鏈結庫和動態鏈結庫》一節的學習,讀者已經了解了什麼是庫檔案、什麼是靜態鏈結庫和動態鏈結庫以及它們之間的區別。同時文章中還提到,在 c、c++ 實際開發過程中,除了可以使用系統庫檔案外,我們還可以根據實際需要,手動建立靜態鏈結庫或者動態鏈結庫。

假設當前有乙個 c 語言專案,其目錄結構如下所示:

demo專案

├─ headers

│ └─ test.h

└─ sources

├─ add.c

├─ sub.c

├─ div.c

└─ main.c

其中,headers 用於表示該專案擁有的所有標頭檔案;sources 表示該專案擁有的所用原始檔,讀者可按照此目錄結構構建 demo 專案,也可以將所有檔案統一放置在 demo 專案下,本節選擇的是後者,即將所有檔案統一放置在 demo 目錄下。

可以看到,該專案中包含 1 個頭檔案( .h ),4 個原始檔( .c ),它們各自包含的**如下所示:

[root@bogon demo]# ls                       

add.c  div.c  main.c  sub.c  test.h

[root@bogon demo]# cat test.h           

#ifndef __test_h_

#define __test_h_

int add(int a,int b);

int sub(int a,int b);

int div(int a,int b);

#endif

[root@bogon demo]# cat add.c           

#include 「test.h」

int add(int a,int b)

return a + b;

[root@bogon demo]# cat sub.c           

#include 「test.h」

int sub(int a,int b)

return a - b;

[root@bogon demo]# cat div.c           

#include 「test.h」

int div(int a,int b)

return a / b;

[root@bogon demo]# cat main.c       

#include

#include "test.h"  //必須引入標頭檔案

int main(void)

int m, n;

printf("input two numbers: ");

scanf("%d %d", &m, &n);

printf("%d+%d=%d\n", m, n, add(m, n));

printf("%d-%d=%d\n", m, n, sub(m, n));

printf("%d÷%d=%d\n", m, n, div(m, n));

return 0;

[root@bogon demo]#

整個專案的邏輯很簡單,其中 add.c、sub.c 和 div.c 這 3 個檔案中各包含乙個函式,分別實現將兩個整數做相加、相減和除法操作,而 test.h 僅包含這 3 個函式的宣告部分,main.c 是主程式檔案,其通過引入 test.h 標頭檔案呼叫了 3 個函式,從而分別完成了對使用者輸入的 2 個整數做相加、相減以及除法操作。

對於編譯、執行 demo 專案,我們可以直接使用 gcc 命令完成:

[root@bogon demo]# gcc main.c add.c sub.c div.c -o main.exe

[root@bogon demo]# ls

add.c  div.c  main.c  main.exe  sub.c  test.h

[root@bogon demo]# ./main.exe

input two numbers: 10 2

10+2=12

10-2=8

10÷2=5

[root@bogon demo]#

注意,由於在程式預處理階段,gcc 編譯器會自行處理各個 .c 檔案內部引入的 .h 標頭檔案(將 .h 檔案中的**直接拷貝到當前 .c 原始檔中),因此編譯執行 demo 專案時,我們只需要提供所有的原始檔即可,不需要處理標頭檔案。

注意,add.c、sub.c 和 div.c 這 3 個檔案,其包含的都是一些功能模組(實現具體功能的函式),對於這樣的原始檔,只要我們願意共享,每個人都可以直接用到自己的專案中。這就產生乙個問題,如果僅希望別人使用我們實現的功能,但又不想它看到具體實現的原始碼,該怎麼辦呢?很簡單,就是將它們加工成乙個靜態鏈結庫。

靜態鏈結庫的建立

原始檔中只提供可以重複使用的**,例如函式、設計好的類等,不能包含 main 主函式;

原始檔在實現具備模組功能的同時,還要提供訪問它的介面,也就是包含各個功能模組宣告部分的標頭檔案。

顯然對於 demo 專案中的 add.c、sub.c 以及 div.c 這 3 個原始檔來說,以上 2 個條件都符合,因此都可以被加工成靜態鏈結庫。並且根據實際需要,我們可以將它們集體壓縮到乙個靜態鏈結庫中,也可以各自壓縮成乙個靜態鏈結庫。

1) 將所有指定的原始檔,都編譯成相應的目標檔案:

[root@bogon demo]# gcc -c sub.c add.c div.c

[root@bogon demo]# ls

add.c  add.o  div.c  div.o  main.c  sub.c  sub.o  test.h

ar rcs 靜態鏈結庫名稱 目標檔案1 目標檔案2 ...

lib***.a

linux 系統下,靜態鏈結庫的字尾名為 .a;windows 系統下,靜態鏈結庫的字尾名為 .lib。

其中,*** 代指我們為該庫起的名字,比如 linux 系統自帶的一些靜態鏈結庫名稱為 libc.a、libgcc.a、libm.a,它們的名稱分別為 c、gcc 和 m。

[root@bogon demo]# ar rcs libmymath.a add.o sub.o div.o

[root@bogon demo]# ls

add.c  add.o  div.c  div.o  libmymath.a  main.c  sub.c  sub.o  test.h

其中,libmymath.a 就是 add.o、sub.o 和 div.o 一起打包生成的靜態鏈結庫,mymath 是我們自定義的庫名。

通過以上 2 步操作,我們就成功建立出了 libmymath.a 靜態鏈結庫。那麼,該如何使用它呢?

靜態鏈結庫的使用

靜態鏈結庫的使用很簡單,就是在程式的鏈結階段,將靜態鏈結庫和其他目標檔案一起執行鏈結操作,從而生成可執行檔案。

以 demo 專案為例,首先我們將 main.c 檔案編譯為目標檔案:

[root@bogon demo]# gcc -c main.c

[root@bogon demo]# ls

add.c  div.c  libmymath.a  main.osub.c

test.h  add.o  div.o  main.c  sub.o

[root@bogon demo]# gcc -static main.o libmymath.a

[root@bogon demo]# ls

add.c  a.out  div.o        main.c  sub.c  test.h

add.o  div.c  libmymath.a  main.o  sub.o

其中,-static 選項強制 gcc 編譯器使用靜態鏈結庫。

[root@bogon demo]# gcc main.o -static -l /root/demo/ -lmymath

[root@bogon demo]# ls

add.c  a.out  div.o        main.c  sub.c  test.h

add.o  div.c  libmymath.a  main.o  sub.o

其中,-l(大寫的 l)選項用於向 gcc 編譯器指明靜態鏈結庫的儲存位置(可以借助 pwd 指令檢視具體的儲存位置); -l(小寫的 l)選項用於指明所需靜態鏈結庫的名稱,注意這裡的名稱指的是 *** 部分,且建議將 -l 和 *** 直接連用(即 -l***),中間不需有空格。

由此,就生成了 a.out 可執行檔案:

[root@bogon demo]# ./a.out

input two numbers: 10 2

10+2=12

10-2=8

10÷2=5

動態鏈結庫 靜態鏈結庫

包含標頭檔案和庫 idir 指定編譯查詢標頭檔案的目錄,常用於查詢第三方的庫的標頭檔案,例 gcc test.c i.inc o test。ldir 指定鏈結時查詢lib的目錄,常用於查詢第三方庫。llibrary 指定額外鏈結的lib庫 巨集定義 dmacro 以字串 1 預設值 定義 macro...

靜態鏈結庫 動態鏈結庫

庫是寫好的現有的,成熟的,可以復用的 現實中每個程式都要依賴很多基礎的底層庫,不可能每個人的 都從零開始,因此庫的存在意義非同尋常。本質上來說庫是一種可執行 的二進位制形式,可以被作業系統載入記憶體執行。庫有兩種 靜態庫 a lib 和動態庫 so dll windows上對應的是.lib dll ...

靜態鏈結庫,動態鏈結庫

關於靜態鏈結庫,參考如下博文 當你完成了 開發,想把這個 給別人用,但是又不希望別人看到原始碼,就要給別人乙個庫和標頭檔案,庫和標頭檔案是配合的,缺一不可。或者過程相反,你從別人那裡拿到乙個庫和標頭檔案來使用。那麼如何編譯生成乙個庫給他人,如何使用從他人那裡拿到的庫呢?範例1 我們想把linuxfr...