使用 GCC 編譯器編譯檔案的時候避免不了連結庫,C語言中有很多的標準庫,使用的時候只需要包含相應的標頭檔案,不需要手動的連結就可以使用標準庫中的內容。當然如果使用自己製作的庫檔案或者是第三方庫的時候需要連結,比如使用第三方庫 Math 中的一些函數,編譯程式的時候需要新增“-lmath”選項。
庫檔案到底是什麼
庫檔案可以分為動態庫檔案和靜態庫檔案,動態庫檔案又稱為共用庫檔案是軟體檔案型別。動態庫和靜態庫是根據連結的時期劃分的:靜態庫的使用是在程式連結階段被複製到程式中,程式執行的時候就不需要靜態庫檔案。動態庫檔案的使用時期是在程式執行的時候被連結的。使用動態庫的優點是系統只需要載入一次動態庫,不同的程式可以得到記憶體中相同的動態庫的副本,因此可以節省記憶體。在Windows中很多的應用程式都不是一個完整的可執行檔案,它們被分割成一些相對獨立的動態連結庫,放置在系統中,當我們執行某一個程式時,相應的動態連結庫檔案就會被使用。
動態庫和靜態庫的異同
不同點:
1. 動態庫是執行時系統呼叫庫函數實現連結,程式碼較小巧,而靜態庫是在連結時複製到程式碼中,程式碼量較龐大,冗餘度高。
2. 正因為靜態庫這種方式也決定了它在連結後不再依賴靜態庫存在,即使靜態庫被刪除程式依然可以正常執行,可移植性強。而動態庫因為是利用本機的庫 函數,所以可能移植到其他電腦會出現執行 bug 等問題,可移植性差。
3. 它們倆的區別在於連結過程的差異,和程式碼被載入的時刻不同
4. 動態庫必須放在指定的目錄下完成連結,而靜態庫給出連結檔案路徑即可
相同點:
1. 庫檔案中都不可以出現主mian函數
2. 這些庫都是提供函數介面,滿足功能的,不暴露原始碼
3. 目的增加程式碼複用,可共用性,減小冗餘
為什麼要使用庫檔案?
在一個程式中,我們經常使用的功能會被封裝到函數或者是類中方便重複使用。對於不同的檔案,有些功能可能會頻繁使用,如果不封裝成庫檔案,我們可能每次都要實現這樣的功能。在 linux 中的一些 C 語言的標準庫就是這樣,使用的時候,只要包含相應的標頭檔案,庫檔案就會自動連結(標準庫)方便我們移植。
另一方面是為了封裝程式碼,有些時候我們不想要讓別人看到實現功能的程式碼,但是可以使用我們實現的功能,這樣就可以製作成庫檔案,也就是程式碼不開源。
Linux檢視依賴庫的方法
-
檢視依賴的庫:objdump -x xxx.so | grep NEEDED
-
檢視可執行程式依賴的庫:objdump -x 可執行程式名 | grep NEEDED
-
檢視缺少的庫:ldd xxx.so