什麼是庫
庫文件是一些預先編譯好的函數的集合,那些函數都是按照可再使用的原則編寫的。它們通常由一組互相關聯的用來完成某項常見工作的函數構成,從本質上來說庫是一種可執行代碼的二進制形式,可以被操作系統載入內存執行。
無論在 Windows 平台還是在Linux平台下都存在大量的庫,但由於 Windows 和Linux的本質不同,因此二者的庫的二進制是不兼容的。
庫的分類
Windows下的庫有兩種:靜態庫(。lib)和動態鏈接庫(。dll)。
Linux下的庫有兩種:靜態庫(。a)和共享庫(。so)。
Linux下的靜態庫的名字一般為libxxxx.a,其中xxxx是該lib的名稱
Linux下的動態庫的名字一般為libxxxx.so.major.minor,xxxx是該lib的名稱,major是主版本號,minor是副版本號。
Windows下的庫與Linux下的庫的異同
Linux的共享庫(。so)就象Windows的動態鏈接庫(。dll),它裡面包含有很多程序常用的函數。為了方便程序開發和減少程序的冗余,程序當中就不用包含每個常用函數的拷貝,只是在需要時調用共享庫中常函數即可。這種方式我們稱之為動態鏈接(Dynamically Linked)。而有時我們不希望叫程序去調用共享庫的函數,而是把庫函數代碼直接鏈接進程序代碼中,也就是說,在程序本身擁有一份共享庫中函數的副本。這種方式我們稱之為靜態鏈接(Statically Linked)。
所以,簡單的講靜態庫和共享庫(動態庫)的不同點在於代碼被載入的時刻不同。
靜態庫的代碼在編譯過程中已經被載入可執行程序,因此體積較大。
共享庫的代碼是在可執行程序運行時才載入內存的,在編譯過程中僅簡單的引用,因此代碼體積較小。
Windows下的動態鏈接庫(。dll)與Linux下的共享庫(。so)的差別
。dll文件事實上和。exe文件一樣,同屬 PE 格式的執行文件。對於隱式的引用外部符號,需要把外部符號所在的位置寫在PE頭上。PE加載器將從PE頭上找到依賴的符號表,並加載依賴的其它。dll文件。
而在Linux 上並非如此!。so文件大多為elf執行文件格式。當它們需要的外部符號,可以不寫明這些符號所在的位置。也就是說,通常。so文件本身並不知道它依賴的那些符號在哪些。so裡面。這些符號是由調用dlopen的進程運行時提供的。
我們在Windows下做一個。dll文件時還需要攜帶一個。lib文件;而在Linux下一般只需要有相應的頭文件就夠了。對於編寫新的。so,找不到的符號可以就讓它在那裡,直到最終執行文件來把所有需要的符號聯合到一起。windows 可以存在一個。dll對另一個。dll的隱式依賴;而Linux下一般不需要讓。so和。so有隱式依賴關系。