1. 程式人生 > >靜態庫和共享庫的區別

靜態庫和共享庫的區別

    根據連結時期不同,庫分為靜態庫和動態庫。靜態庫是在程式編譯時連結的,動態庫是在程式執行時連結的。   庫是預先編譯好的方法的集合 ,linux上庫的命名一般為libxxx.a(靜態庫)libxxx.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          //libfoo.a是庫的名字               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)庫的使用cc -o main main.c -lfoocp  libfoo.so  /usr/lib

  3.總結

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

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

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

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

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

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

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