Linux C 靜態庫(.a) 與 動態庫(.so) 的詳解


從本質上來說是一種可執行代碼的二進制格式,可以被載入內存中執行。庫分靜態庫動態庫兩種。

 

一、靜態庫和動態庫的區別

1、靜態函數庫

這類庫的名字一般是libxxx.a;利用靜態函數庫編譯成的文件比較大--空間,因為整個函數庫的所有數據都會被整合進目標代碼中,他的優點就顯而易見了,即編譯后的執行程序不需要外部的函數庫支持,因為所有使用的函數都已經被編譯進去了。當然這也會成為他的缺點,因為如果靜態函數庫改變了,那么你的程序必須重新編譯。

2、動態函數庫

這類庫的名字一般是libxxx.so;相對於靜態函數庫,動態函數庫在編譯的時候並沒有被編譯進目標代碼中,你的程序執行到相關函數時才調用該函數庫里的相應函數,因此動態函數庫所產生的可執行文件比較小。由於函數庫沒有被整合進你的程序,而是程序運行時動態的申請並調用--時間,所以程序的運行環境中必須提供相應的庫。動態函數庫的改變並不影響你的程序,所以動態函數庫的升級/更新比較方便。

 

二、靜態庫

(一)簡單介紹

/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc \
  main.c src/* -I./include -L./lib -lmpi -o main

/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc 為交叉編譯工具鏈
\為換行,表示下一行與當行為同一行,‘\’后面不能有空格。
main.c 為主函數
src/* 為源文件
-I 后面接頭文件
-L 后面接庫文件路徑
-l 后面接庫文件名,全名為libmpi.a
.a 為靜態庫

(二)編寫及使用靜態庫

(1).設計庫源碼 pr1.c、pr2.c 和 main.c

[bill@billstone make_lib]$ cat pr1.c 
#include 
void print1(void) 
{ 
	printf("This is the first lib src!\n"); 
}

[bill@billstone make_lib]$ cat pr2.c 
#include
void print2(void) 
{ 
	printf("This is the second src lib!\n"); 
}

[bill@billstone make_lib]$ cat main.c 
int main(void) 
{ 
	print1(); 
	print2(); 
	return 0; 
}

(2).編譯pr1.c、pr2.c 文件

[bill@billstone make_lib]$ gcc -O -c pr1.c pr2.c 
[bill@billstone make_lib]$ ls -l pr*.o 
-rw-rw-r--        1 bill          bill                    804    4 月  15 11:11 pr1.o 
-rw-rw-r--        1 bill          bill                    804    4 月  15 11:11 pr2.o 

(3).鏈接靜態庫

為了在編譯程序中正確找到庫文件,靜態庫必須按照 lib[name].a 的規則命名,如下例中[name]=pr.

ar參數意義:

r:在庫中插入模塊(替換)。當插入的模塊名已經在庫中存在,則替換同名的模塊。

s:寫入一個目標文件索引到庫中,或者更新一個存在的目標文件索引。

v:該選項用來顯示執行操作選項的附加信息。

t:顯示庫的模塊表清單。一般只顯示模塊名。

[bill@billstone make_lib]$ ar -rsv libpr.a pr1.o pr2.o 
a - pr1.o 
a - pr2.o 

[bill@billstone make_lib]$ ar -t libpr.a 
pr1.o 
pr2.o 

(4).編譯鏈接選項

-L-l 參數放在后面。其中,-L 加載庫文件路徑,-l 指明庫文件名字。

[bill@billstone make_lib]$ gcc -o main main.c -L./ -lpr     // 生成main

(5).執行目標程序

[bill@billstone make_lib]$ ./main 
This is the first lib src! 
This is the second src lib!

 

三、動態庫(隱式調用)

(1).設計庫代碼

[bill@billstone make_lib]$ cat pr1.c 
#include 
int p = 2; 
void print() { 
	printf("%p:%d\n", &p, p);
	printf("This is the first dll src!\n"); 
} 

(2).生成動態庫 xxx.so

[bill@billstone make_lib]$ gcc -O -fpic -shared -o xxx.so pr1.c 
[bill@billstone make_lib]$ ls -l *.so 
-rwxrwxr-x        1 bill          bill                  6592    4 月  15 15:19 xxx.so 

(3).動態庫的隱式調用

[bill@billstone make_lib]$ cat main.c 
int main() 
{ 
	print(); 
	return 0; 
}

[bill@billstone make_lib]$ gcc -o main main.c ./xxx.so 

[bill@billstone make_lib]$ ./main 
0x97b5d4:2
this is the first lib src!

當動態庫的位置發生改變時,程序將無法正常運行,而動態庫取代靜態庫的好處之一則是通過更新動態庫而隨時升級庫的內容。 

 

 

附:

【圖】C/C++ 靜態鏈接庫 與 動態鏈接庫


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM