本文有更新,請移步個人我的博客:https://blog.andyqiao.top/article/10/編程
-
加載(load)
- 將程序拷貝到存儲器並運行的過程,由加載器(loader)執行。
-
連接分類
- 編譯時(compile time)連接:也稱爲傳統靜態連接、靜態連接;
- 加載時(load time)連接:在程序被加載的時候動態連接共享庫;
- 運行時(run time)連接:在程序運行時根據須要動態連接共享庫。
-
目標文件
- 可重定位目標文件:可被連接生成可執行目標文件;
- 可執行目標文件:可被直接拷貝至存儲器中運行;
- 共享目標文件:能夠在加載或者運行時被動態地加載到存儲器並連接。
-
庫分類
- 靜態庫:只能在編譯時被靜態連接 .a;
- 共享庫:能夠加載時連接或運行時連接 .so .dll 。
-
靜態庫
- 本質上是一組可重定位目標文件,在連接時,靜態連接器只拷備被程序引用的目標模塊:
- 優勢
- 將一組可重定位目標文件打包至一個靜態庫,方便使用;
- 在連接時,只拷備被引用模塊,減少可執行文件的大小;
- 應用舉例:C語言的衆多庫函數有如下幾種打包方式:
- 編譯器自動識別並連接:優(1 方便編程),缺(1 C庫函數過多,使編譯器變得複雜;2 升級時必須更新編譯器版本);
- 將全部C庫函數放入一個可重定位目標模塊:優(1 方便連接,2 方便升級),缺(1 連接時會拷備全部函數,引發代碼量過大);
- 將每一個庫函數放入多個可重定位目標模塊:優(1 最終程序代碼量小),缺(1 不方便連接);
- 將全部庫函數打包成一個靜態庫:優(1 方便升級;2 方便連接;3 最終程序代碼量小),缺(1 庫函數升級時,必須從新編譯程序;2 不能在程序之間共享庫函數)
-
共享庫
- 兩種方式
- 加載時連接:當建立可執行文件時,靜態執行一部分連接,而後在程序加載時,動態完成連接過程。
- 運行時連接:在程序運行過程當中打開共享庫、定位符號地址、完成使用、關閉共享庫;
- 應用舉例:軟件升級(Windows的一些升級就經過更新共享庫來完成);
- Linux API:dlopen(打開並加載共享庫)、dlsym(獲取符號地址)、dlclose(關閉共享庫)。
- 與靜態庫區別
- 在加載時/運行時連接,而不是編譯時連接;
- 升級能夠經過直接替換共享庫文件,而不須要從新編譯;
- 運行時連接能夠實如今程序之間共享庫函數。