靜態庫和共享庫的區別

2021-08-19 20:20:17 字數 1974 閱讀 8060

根據鏈結時期不同,庫分為靜態庫和動態庫。靜態庫是在程式編譯時鏈結的,動態庫是在程式執行時鏈結的。

庫是預先編譯好的方法的集合 ,linux上庫的命名一般為lib***.a(靜態庫)lib***.so(動態庫),庫檔案常存放的地點為/lib或/usr/lib,庫對應的標頭檔案一般存放在/usr/include中

下面介紹兩種庫:

1.靜態庫的生成

若有兩種方法int add(int a,int b),int max(int a,int b)分別在兩個檔案add.c和max.c中存放,則靜態庫的生成過程如下

1):將所有的.c檔案編譯成.o目標檔案

gcc -c add.c      生成add.o

gcc -c max.c      生成max.o

2) : 對生成的.o目標檔案打包生成靜態庫

ar crv libfoo.a add.o max.o          是庫的名字

ar:做庫的命令

c:建立庫

r:將方法新增到庫里

v:顯示過程,可以不要

3):使用靜態庫  

gcc -o main main.c -l. -lfoo       //這裡寫的foo是去掉字首字尾後的名字

-l:指定路徑 .代表當前路徑

-l:指定庫名

2 ,共享庫的生成

1)將所有的.c檔案編譯成.o目標檔案

gcc -c max.c

gcc -c add.c

2) 對生成的.o檔案處理生成共享庫,假設共享庫的名字為libfoo.so

gcc -shared -fpic -o libfoo.so add.o max.o

引數-shared 表示輸出結果是共享庫型別的

-fpic 表示使用位址無關**(position independent code)技術來生產輸出檔案

3)庫的使用

3.總結

鏈結靜態庫其實從某種意義上來說也是一種貼上複製,只不過它操作的物件是目標**而不是原始碼而已。因為靜態庫被鏈結後庫就直接嵌入可執行檔案中了,這樣就帶來了兩個問題。

首先就是系統空間被浪費了。這是顯而易見的,想象一下,如果多個程式鏈結了同乙個庫,則每乙個生成的可執行檔案就都會有乙個庫的副本,必然會浪費系統空間。

一旦發現了庫中有bug,挽救起來就比較麻煩了。必須一一把鏈結該庫的程式找出來,然後重新編譯。

而動態庫的出現正彌補了靜態庫的以上弊端。因為動態庫是在程式執行時被鏈結的,所以磁碟上只須保留乙份副本,因此節約了磁碟空間。如果發現了bug或要公升級也很簡單,只要用新的庫把原來的替換掉就行了。

那麼,是不是靜態庫就一無是處了呢?

答:非也非也。想象一下這樣的情況:如果你用libpcap庫編了乙個程式,要給被人執行,而他的系統上沒有裝pcap庫,該怎麼解決呢?最簡單的辦法就是編譯該程式時把所有要鏈結的庫都鏈結它們的靜態庫,這樣,就可以在別人的系統上直接執行該程式了。

正因為動態庫在程式執行時被鏈結,故程式的執行速度和鏈結靜態庫的版本相比必然會打折扣。然而瑕不掩瑜,動態庫的不足相對於它帶來的好處在現今硬體下簡直是微不足道的,所以鏈結程式在鏈結時一般是優先鏈結動態庫的,除非用-static引數指定鏈結靜態庫。

靜態庫和共享庫 動態庫 的區別

靜態庫和共享庫 動態庫 的區別 根據鏈結時期不同,分為靜態庫和共享庫,靜態庫是在程式編譯時鏈結的,共享庫是在程式執行時鏈結的。庫是預先編譯好的方法的集合,命名一般為libxx.a 靜態庫 libxx.so 動態庫 庫檔案常存放的地點為 lib或 usr lib,庫對應的標頭檔案一般存放在 usr i...

靜態庫和共享庫

建立和使用靜態庫 1 建立目錄 mkdir p test sub 2 在子目錄sub 下編寫hello.c和hello.h hello.c include include hello.h void hello hello.h include void hello 4 在主目錄test 下編寫main...

靜態庫和共享庫(二)

brary值 2 動態鏈結緩衝檔案 etc ld.so.cache 3 目錄 lib,usr lib flag表示在什麼時候解決未定義的符號 呼叫 取值有兩個 1 rtld lazy 表明在動態鏈結庫的函式 執行時解決.2 rtld now 表明在dlopen返回前就解決所有未定義的符號,一旦未解決...