當前位置:才華齋>計算機>C語言>

C語言連結庫的用法

C語言 閱讀(9.35K)

庫檔案簡單了說就是包含了別人(或者自己)已經寫好的程式碼,可以直接呼叫的其內部函式的檔案。庫檔案又包含動態庫檔案和靜態庫檔案。為什麼有靜態庫和動態庫的區別,我簡單的介紹一下我所理解的什麼是靜態庫,什麼又是動態庫。下面是小編為大家帶來的C語言連結庫的用法,歡迎閱讀。

C語言連結庫的用法

  0x01 連結庫的簡單理解與編譯命令

庫檔案簡單了說就是包含了別人(或者自己)已經寫好的`程式碼,可以直接呼叫的其內部函式的檔案。庫檔案又包含動態庫檔案和靜態庫檔案。為什麼有靜態庫和動態庫的區別,我簡單的介紹一下我所理解的什麼是靜態庫,什麼又是動態庫。

  靜態庫

Linux系統下字尾名為*.a

Windows系統下字尾名為*

呼叫靜態庫,在編譯器進行編譯過程中,在有需要呼叫到庫檔案內部函式的地方,編譯器會將靜態庫裡的函式實現過程,拷貝到函式呼叫的地方。在編譯好的程式執行時,不需要依賴庫檔案,可以獨立執行。庫檔案對程式碼複用性很高,容易理解也容易使用,對提高開發速率有很大幫助,不需要自己造輪子。

Linux下生成靜態庫檔案命令

$ gcc -c [FileName].c // 生成*.o檔案

$ ar -crv [FileName].a [FileName].o // 生成*.a檔案

  動態庫

Linux系統下檔名格式為lib*.so

Windows系統下字尾名*.dll

上面介紹了靜態庫在編譯過程中,編譯器會將函式實現拷貝到可執行檔案中,所以在程式執行時會佔用一定的資源,造成資源浪費,而且在庫檔案的版本更新中,一點微小的改動,就需要對整個程式進行重新編譯釋出,在使用者使用過程中,這是得不償失的。而動態庫,則改進了靜態庫的這些缺點。簡單介紹兩個方面:

1、靜態庫在編譯過程中不需要將程式碼編譯到可執行程式中,在程式執行時需要呼叫的時候才載入。解決了在開發程式中使用靜態庫版本更新的問題,使用動態庫不需要將自己編寫的程式重新編譯,更新庫和更新程式是獨立的兩項任務。

2、可以實現庫共享,不同程式的相同功能程式碼的實現可以只需要一份庫檔案提供呼叫,比如jpeg影象編碼功能,很多程式都需要進行影象處理,簡單的Logo頭像的顯示到複雜的平面設計,不同的軟體可能使用的都是同一份庫檔案。

雖然動態庫相對靜態庫優化了很多缺點,但並不是說可以完全不需要靜態庫。在內部開發的時候,兩個同事對同一個專案的不同子功能進行開發,這些功能具有相互聯絡,但是又不希望對外部人員提供引用,在程式釋出時,打包編譯所有的程式碼實現都編譯到程式中。

  Linux下編譯生成動態庫檔案

$ gcc -fPIC -c [FileName].c

$ gcc -shared -o lib[FileName] [FileName].o

也可以一條命令編譯

gcc -fPIC -shared [FileName].c -o lib[Name]

  0x02 庫的程式設計使用

我主要使用簡單的程式設計例項介紹動態庫的使用,靜態庫的使用方法與之相同。

我所舉的例子中編寫了3份檔案

1、libtest.c // 庫函式實現,最終將此檔案編譯成庫檔案

2、test.h // 測試標頭檔案,檔案內只有一個結構體變數

3、main.c // 測試程式碼主函式的實現

ps: test.h標頭檔案中只提供了一個結構體,庫檔案並不提供新的變數型別引用,新的變數一定需要定義

直接呈上程式碼

test.h:

/** test.h **/

#ifndef TEST_H

#define TEST_H

typedef struct {

int a;

char b;

}Test_t;

#endif

libtest.c:

/** libtest.c **/

#include

#include

#include "./test.h"

int fun1(int a)

{

return a*2;

}

Test_t *fun2(Test_t a)

{

a.a++;

a.b = 's';

Test_t *b = malloc(sizeof(Test_t));

*b = a;

return b;

}

很簡單的內容,兩個函式,fun1()和fun2()

先編譯庫檔案

$ gcc -fpic -shared libtest.c -o

main.c:

/** main.c **/

#include

#include

#include "./test.h"

int main()

{

//struct TEST_T A;

Test_t A;

A.a = 10;

A.b = 'w';

printf("[init] Test.a = %d ", A.a);

printf("[init] Test.b = %c", A.b);

printf("");

printf("[call] fun1() = %d", fun1(A.a));

printf("");

Test_t *B;

B = (Test_t *)fun2(A); // 加強制轉換

printf("[call] fun2().a = %d", B->a);

printf("[call] fun2().b = %c", B->b);

printf("");

free(B);

}

編譯主程式

$ gcc main.c -L./ -ltest -I./ -o main

  0x03 測試&結果

wangsansan@ubuntu$ ./main

[init] Test.a = 10 [init] Test.b = w

[call] fun_test() = 20

[call] fun2_test().a = 11

[call] fun2_test().b = s

wangsansan@ubunut$