久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

linux下靜態鏈接庫和動態鏈接庫的區別有哪些

171次閱讀
沒有評論

共計 3069 個字符,預計需要花費 8 分鐘才能閱讀完成。

這篇文章主要講解了“linux 下靜態鏈接庫和動態鏈接庫的區別有哪些”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著丸趣 TV 小編的思路慢慢深入,一起來研究和學習“linux 下靜態鏈接庫和動態鏈接庫的區別有哪些”吧!

區別:1、動態庫的后綴為“.so”,靜態庫的后綴為“.a”。2、如果靜態函數庫改變了,那么程序必須重新編譯;而動態函數庫的改變并不影響程序。3、相對于靜態庫,動態庫在編譯的時候并沒有被編譯進目標代碼中,用戶的程序執行到相關函數時才調用該函數庫里的相應函數,因此動態函數庫所產生的可執行文件比較小。

一、庫的基礎概念:

在 windows 平臺和 linux 平臺下都大量存在著庫。本質上來說庫是一種可執行代碼的二進制形式,可以被操作系統載入內存執行。由于 windows 和 linux 的本質不同,因此二者庫的二進制是不兼容的。通俗的說就是把這些常用函數的目標文件打包在一起,提供相應函數的接口,便于程序員使用。在使用函數時,只需要包對應的頭文件即可。按照庫的使用方式又可分為動態庫和靜態庫,在不同平臺下對應后綴也有所不同。

WINDOWS 下:.dll 后綴為動態庫,.lib 后綴為靜態庫;

LINUX 下:.so 后綴為動態庫,.a 后綴為靜態庫。

二、靜態庫與靜態鏈接

1 靜態庫:

靜態庫可以簡單的看成一組目標文件的集合,即很多目標文件經過壓縮打包后形成的文件。比如在我們日常編程中,如果需要使用 printf 函數,就需要包 stdio.h 的庫文件,使用 strlen 時,又需要包 string.h 的庫文件,可是如果直接把對應函數源碼編譯后形成的.o 文件直接提供給我們,將會對我們的管理和使用上造成極大不便,于是可以使用“ar”壓縮程序將這些目標文件壓縮在一起,形成 libx.a 靜態庫文件。

注:靜態庫命名格式:lib + 庫名稱”+ .a(后綴) 例:libadd.a 就是一個叫 add 的靜態庫

2 靜態鏈接:

對于靜態庫,程序在編譯鏈接時,將庫的代碼鏈接到可執行文件中,程序運行時不再需要靜態庫。在使用過程中只需要將庫和我們的程序編譯后的文件鏈接在一起就可形成一個可執行文件。

通過一個例子來了解下如何將我們自己寫的頭文件和代碼同時進行編譯鏈接,最終生成可執行文件:

/main.c/
#include  stdio.h 
#include  add.h 
int main()
 int ret = add(3, 4);
 printf(3 + 4 = %d\n ,ret);
 return 0;
/add.c/
#include  add.h 
int add( int x, int y)
 return x + y;

main : main.c libadd.a gcc main.c -L . -ladd -o main //- L 為指定路徑  . 為當前目錄下  -l+ 庫名字,編譯器可在指定目錄下自己尋找名為 add 的庫文件 libadd.a :  gcc -c add.c -o add.o //ar -rc 將多個編譯后的文件打包為一個靜態庫文件 ar -rc libadd.a add.o .PHONY:clean clean: rm main libadd.a

make 后輸出截圖:

3 缺點:

1、內存和磁盤空間浪費:靜態鏈接方式對于計算機內存和磁盤的空間浪費十分嚴重。

假如一個 c 語言的靜態庫大小為 1MB,系統中有 100 個需要使用到該庫文件,采用靜態鏈接的話,就要浪費進 100M 的內存,若數量再大,那浪費的也就更多。例如下圖:程序 1 和程序 2 都需要用到 Lib.o,采用靜態鏈接的話,那么物理內存中就會存放兩份對應此文件的拷貝。

2、更新麻煩:

比如一個程序 20 個模塊,每個模塊只有 1MB,那么每次更新任何一個模塊,用戶都得重新下載 20M 的程序。

三、動態庫與動態鏈接

1 動態庫:

程序在運行時才去鏈接動態庫的代碼,多個程序共享庫的代碼。一個與動態庫鏈接的可執行文件僅僅包含它用到的函數入口地址的一個表,而不是外部函數所在目標文件的整個機器碼。

注:動態庫命名格式:lib + 庫名稱”+ .so(后綴) 例:libadd.so 就是一個叫 add 的動態庫

2 動態鏈接:

由于靜態鏈接具有浪費內存和模塊更新困難等問題,提出了動態鏈接?;緦崿F思想是把程序按照模塊拆分成各個相對獨立部分,在程序運行時才將他們鏈接在一起形成一個完整的程序,而不是像靜態鏈接那樣把所有的程序模塊都鏈接成一個單獨的可執行文件。所以動態鏈接是將鏈接過程推遲到了運行時才進行。

同樣,假如有程序 1,程序 2,和 Lib.o 三個文件,程序 1 和程序 2 在執行時都需要用到 Lib.o 文件,當運行程序 1 時,系統首先加載程序 1,當發現需要 Lib.o 文件時,也同樣加載到內存,再去加載程序 2 當發現也同樣需要用到 Lib.o 文件時,則不需要重新加載 Lib.o,只需要將程序 2 和 Lib.o 文件鏈接起來即可,內存中始終只存在一份 Lib.o 文件。

動態庫和動態鏈接的例子依然使用上面的代碼,輸出結果也相同,唯一需要改變的就是 Makefile 文件。

/Makefile/
main : main.c libadd.so
 gcc main.c -L . -ladd -o main
libadd.so : 
 gcc -fPIC -shared add.c -o libadd.so
 //-shared 表示輸出結果是共享庫類型的  -fPIC 表示使用地址無關代碼奇數來生產輸出文件
.PHONY:clean
clean:
 rm main libadd.so

當我們生成可執行文件后,可使用 ldd 命令查看該可執行文件所依靠的動態庫。

前面提到 windows 和 Linux 下庫文件的后綴不同,更根本的原因在于二者文件格式都不同。可以通過 file 一個動態庫查看 Linux 下動態庫的文件類型其實是 ELF 格式。ELF 動態鏈接文件被稱為動態共享對象 (DSO,Dynamic Shared Objects),簡稱共享對象;在 windows 下,動態鏈接文件被稱為動態鏈接庫(Dynamic Linking Library),也就是.dll 文件后綴的全稱。

3 優點:

①毋庸置疑的就是節省內存;

②減少物理頁面的換入換出;

③在升級某個模塊時,理論上只需要將對應舊的目標文件覆蓋掉即可。新版本的目標文件會被自動裝載到內存中并且鏈接起來;

④程序在運行時可以動態的選擇加載各種程序模塊,實現程序的擴展。

四、靜態庫和動態庫的區別

1. 靜態庫

這類庫的名字一般是 libxxx.a;利用靜態函數庫編譯成的文件比較大,因為整個 函數庫的所有數據都會被整合進目標代碼中,他的優點就顯而易見了,即編譯后的執行程序不需要外部的函數庫支持,因為所有使用的函數都已經被編譯進去了。當然這也會成為他的缺點,因為 如果靜態函數庫改變了,那么你的程序必須重新編譯。

2. 動態庫

這類庫的名字一般是 libxxx.so ; 相對于靜態函數庫,動態函數庫在編譯的時候并沒有被編譯進目標代碼中,你的程序執行到相關函數時才調用該函數庫里的相應函數,因此動態函數庫所產生的可執行文件比較小。由于函數庫沒有被整合進你的程序,而是程序運行時動態的申請并調用,所以程序的運行環境中必須提供相應的庫。動態函數庫的改變并不影響你的程序,所以動態函數庫的升級比較方便。

感謝各位的閱讀,以上就是“linux 下靜態鏈接庫和動態鏈接庫的區別有哪些”的內容了,經過本文的學習后,相信大家對 linux 下靜態鏈接庫和動態鏈接庫的區別有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是丸趣 TV,丸趣 TV 小編將為大家推送更多相關知識點的文章,歡迎關注!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-12發表,共計3069字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 黄龙县| 北宁市| 光山县| 漳浦县| 红桥区| 万盛区| 邵东县| 遂平县| 武宣县| 远安县| 余干县| 永宁县| 威宁| 岳阳县| 横山县| 古田县| 岱山县| 宜都市| 桐梓县| 深水埗区| 北安市| 岳西县| 广西| 油尖旺区| 阳曲县| 南江县| 临沧市| 商丘市| 五常市| 河源市| 屏东县| 新绛县| 永福县| 弥勒县| 顺义区| 永昌县| 花莲市| 浪卡子县| 红安县| 荥阳市| 静安区|