欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報激活碼778899分享:【Linux】靜態(tài)庫和動態(tài)庫

柚子快報激活碼778899分享:【Linux】靜態(tài)庫和動態(tài)庫

http://yzkb.51969.com/

> 作者:?舊言~ > 座右銘:松樹千年終是朽,槿花一日自為榮。

> 目標(biāo):理解靜動態(tài)庫,自己能模擬實(shí)現(xiàn)動靜態(tài)庫。

> 毒雞湯:有些事情,總是不明白,所以我不會堅持。早安!

> 專欄選自:Linux初階

> 望小伙伴們點(diǎn)贊?收藏?加關(guān)注喲??

?

?前言

庫是寫好的現(xiàn)有的,成熟的,可以復(fù)用的代碼?,F(xiàn)實(shí)中每個程序都要依賴很多基礎(chǔ)的底層庫,不可能每個人的代碼都從零開始,因此庫的存在意義非同尋常。本質(zhì)上來說庫是一種可執(zhí)行代碼的二進(jìn)制形式,可以被操作系統(tǒng)載入內(nèi)存執(zhí)行。庫有兩種:

靜態(tài)庫(.a、.lib)動態(tài)庫(.so、.dll)

今天我們來談?wù)? Linux? 下靜態(tài)庫和動態(tài)庫。

?主體

學(xué)習(xí)【Linux】靜態(tài)庫和動態(tài)庫咱們按照下面的圖解:

?

? 認(rèn)識動靜態(tài)庫

Linux的庫一般分為動態(tài)庫和靜態(tài)庫:

靜態(tài)庫(.a):庫文件以.a為后綴,程序在編譯鏈接的時候把庫的代碼鏈接到可執(zhí)行文件中。程序運(yùn)行的時候?qū)⒉辉傩枰o態(tài)庫動態(tài)庫(.so):庫文件以.so為后綴,程序在運(yùn)行的時候才去鏈接動態(tài)庫的代碼,多個程序共享使用庫的代碼。

在Xshell下安裝靜態(tài)庫:

yum install -y glibc-static

yum install -y libstdc++-static

我們可以通過 [?ldd 可執(zhí)行程序文件名?]來查看可執(zhí)行程序所依賴的庫:

?

其中?/lib64/libc.so.6?就是可執(zhí)行程序的庫文件,它其實(shí)是一個軟鏈接。我們可以通過以下命令來查看

ls /lib64/libc.so.6 -l

?

總結(jié):

如何辨別它采用的是哪一種庫呢?

1.我們可以通過后綴來區(qū)分(在Linux中)

在Linux中,以 .so 結(jié)尾的后綴,是動態(tài)庫;以 .a 結(jié)尾的是靜態(tài)庫 ?在Windows中,以 .dll 結(jié)尾的后綴,是動態(tài)庫;以 .lib 結(jié)尾的是靜態(tài)庫 ?

注:

庫文件的名字:libxxx.so 和 libxxx.a庫的真實(shí)名字:去掉lib前綴,去掉 .a 、.so后綴,剩下的就是庫的名稱。

2.我們還可以通過file命令查看

?

? ? ? ? 上圖中分別使用了動靜態(tài)庫對同一個文件進(jìn)行編譯的,通過file命名可以查看到所對應(yīng)的鏈接信息

? 理解什么是庫

概念:

如果不想給對方我們的源代碼,我們可以選擇給用戶提供我們的.o可重定位目標(biāo)二進(jìn)制文件(gcc -c 文件)與.h頭文件。讓用戶用我們提供的.o文件進(jìn)行鏈接即可。在編譯時,只要把源文件編譯成.o文件在將其鏈接便可形成一個可執(zhí)行的程序。

圖解:

?

舉個栗子:

案例:

?

說明:

難道就這么簡單嗎?我們可以給對方提供.o(方法的實(shí)現(xiàn)),同時還有提供.h(里面包含著都有哪些方法),此時對方是能用的。但是如果存在很多.c文件呢?難道我們要把幾千個.c文件全部編譯成.o在加上頭文件全部一個一個提供嗎?那樣太過于麻煩,為了讓用戶更好的使用庫,我們就有把所有的.o文件打成一個包,給對方提供一個庫文件即可!把多個.o合并成一個文件,這個文件就是庫,把包方式的不同就分為了動態(tài)庫和靜態(tài)庫*。

? 庫的制作和使用

概念:

庫是一個二進(jìn)制文件,想要使用庫(給別人使用自己的制作的庫或者使用別人的庫)一定是由三個部分組成:庫文件、頭文件、文檔說明;一般這個庫文件就是函數(shù)的定義,頭文件就是函數(shù)聲明,我們只需要將這些打包好,別人使用我們頭文件所給的接口就行。

編寫如下四個文件:用來制作靜態(tài)庫并打包

源文件包含add.c和sub.c頭文件包含add.h和sub.h

?

??靜態(tài)庫的制作

1.生成二進(jìn)制(.o)文件

?

2.打包

我們將生成好的.o文件進(jìn)行打包:

ar -rc libmymath.a add.o sub.o

ar命令是gnu的歸檔工具,常用于將目標(biāo)文件打包為靜態(tài)庫,下面我們使用ar命令的-r 選項(xiàng)和-c選項(xiàng)進(jìn)行打包。

-r(replace):若靜態(tài)庫文件當(dāng)中的目標(biāo)文件有更新,則用新的目標(biāo)文件替換舊的目標(biāo)文件。-r(rreate):建立靜態(tài)庫文件。

?

我們可以用?ar?命令的?-t?選項(xiàng)和?-v?選項(xiàng)查看靜態(tài)庫當(dāng)中的文件。

-t:列出靜態(tài)庫中的文件。-v:顯示詳細(xì)的信息

?

3.發(fā)布靜態(tài)庫

靜態(tài)庫要發(fā)布出去供別人使用,只要庫文件(所有的.o文件)是不夠的,我們需要將其和頭文件一起發(fā)布出去,別人只要看到頭文件,就大致了解如何使用了

?

??靜態(tài)庫的使用

問題拋出?

上文中,我們已經(jīng)有了靜態(tài)庫output了,別人該如何使用呢? 例如:想要在friend文件下使用這個庫:

方法一 :

?

現(xiàn)在在friend目錄下有一個mytest.c文件和一個靜態(tài)庫文件lib,mytest.c想要使用lib,我們先編寫一下mytest.c代碼:

#include "add.h"

#include "sub.h"

int main()

{

int x = 30;

int y = 20;

int ret1 = my_add(x, y);

int ret2 = my_sub(x, y);

printf("ret1 = %d\n",ret1);

printf("ret2 = %d\n",ret2);

return 0;

}

編譯:

?

說明:

編譯后,報警告:沒有頭文件,可是明明在lib文件下有我們要的有文件以及庫文件,這是為什么呢?

?其實(shí),編譯器在編譯的時候,會在當(dāng)前的目錄的文件中去找,不會去當(dāng)前目錄的文件夾中去找,lib目錄下的頭文件以及庫文件,和mytest.c不是同級目錄,所以編譯會出錯;我們在編譯的時候就需要告訴編譯器,需要的頭文件在哪個目錄下。

gcc mytest.c -I ./lib

?

此時,又有警告了:鏈接錯誤,未定義的兩個函數(shù)?在lib目錄下已經(jīng)定義了兩個函數(shù),并且打包好了?為什么還是報錯呢?

其原因和上面一樣;所以我們還需要告訴編譯器庫文件在lib目錄下:

gcc mytest.c -I ./lib -L ./lib

?

頭文件和庫文件所在位置都告訴編譯器了,怎么還是報錯呢?

其實(shí),頭文件和庫文件都在lib目錄下,在mytest.c文件中,是明確的包含了,add.h和sub.h的,gcc在編譯的時候能夠認(rèn)識,但不認(rèn)識庫文件,如果在lib目錄下有多個庫文件,gcc是不知道你想要使用哪個庫的。所以我們還需要指明庫的名字。

gcc mytest.c -I ./lib -L ./lib -l mymath

?

方法二:

對比我們之前在編譯某個.c文件時,為什么有加上這些選項(xiàng)呢?。這是因?yàn)橹暗膸於际窃谙到y(tǒng)的默認(rèn)路徑下,所以我們可以將我們做好的靜態(tài)庫拷貝到系統(tǒng)的默認(rèn)路徑下,也是可以達(dá)到不需要加這些選項(xiàng)的效果;但是嚴(yán)重不推薦。

總結(jié):

我們在使用靜態(tài)庫進(jìn)行編譯鏈接時,需要指定頭文件的所在路徑,庫文件的所在路徑以及所要掉用的庫名稱

-I:指定頭文件所在路徑。-L:指定庫文件所在路徑。-l:指明需要鏈接庫文件路徑下的哪一個庫

?

? 動態(tài)庫的制作

編寫如下四個文件:其中源文件包含add.c和sub.c,頭文件包含add.h和sub.h;用來制作動態(tài)庫并打包

?

1.生成二進(jìn)制(.o)文件

首先將上面的.c文件生成.o文件?

gcc -fPIC -c add.c -o add.o

gcc -fPIC -c sub.c -o sub.o

-fPIC:作用是告知編譯器 生成位置無關(guān)代碼(編譯產(chǎn)生的代碼沒有絕對位置,只有相對位置);從而可以在任意地方調(diào)用生成的動態(tài)庫。

?

2.打包

?我們將生成好的.o文件進(jìn)行打包:

gcc -shared -o libmymath.so add.o sub.o

-shared:linux在gcc編譯時加上 -shared 參數(shù)時,目的是使源碼編譯成動態(tài)庫 .so 文件;

?

3.發(fā)布動態(tài)庫

將庫文件和所有的頭文件組織起來,放到lib目錄下,這樣就可以發(fā)布動態(tài)庫了

?

? 動態(tài)庫的使用

動態(tài)庫的使用大致和靜態(tài)庫類似,但略有區(qū)別。我們先使用靜態(tài)庫的方法來實(shí)現(xiàn)動態(tài)庫的鏈接。

?

方法一:

?拷貝到系統(tǒng)的默認(rèn)路徑下,一般指/usr/lib?這里不做演示,嚴(yán)重不推薦;

方法二 :

更改 ?LD_LIBRARY_PATH

export LD_LIBRARY_PATH=/home/lyk/lesson8/friend/lib

?LD_LIBRARY_PATH環(huán)境變量用于在程序加載運(yùn)行期間查找動態(tài)鏈接庫時指定除了系統(tǒng)默認(rèn)路徑之外的其他路徑.注意,LD_LIBRARY_PATH中指定的路徑會在系統(tǒng)默認(rèn)路徑之前進(jìn)行查找;

添加好后,我們再次查看,發(fā)現(xiàn)路徑已經(jīng)指定好了 :

再次編譯運(yùn)行:?

? 動靜態(tài)庫的加載

靜態(tài)庫不需要加載,靜態(tài)庫把代碼拷貝到可執(zhí)行程序里,直接決定了當(dāng)加載的時候在內(nèi)存里代碼和數(shù)據(jù)可能存在多份,會比較浪費(fèi)空間,把靜態(tài)庫中拷貝到程序中的代碼區(qū)里:

動態(tài)庫加上fPIC形成位置無關(guān)碼,采用相對編址方案,在程序鏈接時對應(yīng)庫當(dāng)中的偏移量添加到可執(zhí)行程序,運(yùn)行時一旦庫加載進(jìn)來,經(jīng)過地址空間映射,把庫映射到地址空間之后,庫也就具備了起始地址,通過偏移地址和起始地址這樣就可以找到訪問的函數(shù):

系統(tǒng)層面上會維護(hù)動態(tài)庫的起始地址,直接建立頁表與內(nèi)存的映射,也就可以跳轉(zhuǎn)訪問了,所以動態(tài)庫加載一次就可以被多個進(jìn)程共同使用了。而靜態(tài)庫可能有多個程序用了C庫,加載到內(nèi)存時,內(nèi)存里可能會存在100份重復(fù)的代碼。而動態(tài)鏈接不會出現(xiàn)重復(fù)的代碼,減少內(nèi)存。

? 動靜態(tài)庫總結(jié)

靜態(tài)庫的特點(diǎn):

靜態(tài)庫在可執(zhí)行程序鏈接時就加入到可執(zhí)行代碼中,在物理上成為可執(zhí)行程序的一部分;程序運(yùn)行時將不再需要該靜態(tài)庫。相對于動態(tài)庫鏈接生成的程序,靜態(tài)函相當(dāng)于編譯器將代碼補(bǔ)充完整了,因此執(zhí)行程序會大一些,但是運(yùn)行起來相對快些;靜態(tài)庫是犧牲了空間效率,換取了時間效率;

動態(tài)庫的特點(diǎn):

動態(tài)庫在程序編譯時并不會被連接到目標(biāo)代碼中,而是在程序運(yùn)行是才被載入,因此在程序運(yùn)行時還需要動態(tài)庫存在;動態(tài)庫只有在程序執(zhí)行時, 那些需要的函數(shù)代碼才被拷貝到內(nèi)存中。這樣就使可執(zhí)行文件比較小, 節(jié)省磁盤空間;由于運(yùn)行時要去鏈接庫會花費(fèi)一定的時間,執(zhí)行速度相對會慢一些;動態(tài)庫是犧牲了時間效率,換取了空間效率;

??結(jié)束語?

? ? ? ?今天內(nèi)容就到這里啦,時間過得很快,大家沉下心來好好學(xué)習(xí),會有一定的收獲的,大家多多堅持,嘻嘻,成功路上注定孤獨(dú),因?yàn)閳猿值娜瞬欢?。那請大家舉起自己的小手給博主一鍵三連,有你們的支持是我最大的動力???,回見。

??

柚子快報激活碼778899分享:【Linux】靜態(tài)庫和動態(tài)庫

http://yzkb.51969.com/

文章來源

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。

轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://m.gantiao.com.cn/post/18807510.html

發(fā)布評論

您暫未設(shè)置收款碼

請在主題配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問

文章目錄