Linux 中的動態鏈結庫和靜態鏈結庫是幹什麼的?

2021-10-10 11:06:05 字數 2706 閱讀 6657

什麼是庫?
庫是寫好的現有的,成熟的,可以復用的**。現實中每個程式都要依賴很多基礎的底層庫,不可能每個人的**都從零開始,因此庫的存在意義非同尋常

本質上來說庫是一種可執行**的二進位制形式,可以被作業系統載入記憶體執行。庫有兩種:靜態庫(.a、.lib)和動態庫(.so、.dll)。 windows上對應的是.lib .dll linux上對應的是.a .so

在這裡先介紹下linux下的gcc編譯的幾個選項

g++ -c hellospeak.cpp
會將hellospeak.cpp 選項 -c 用來告訴編譯器編譯源**但不要執行鏈結,輸出結果為物件檔案。檔案預設名與原始碼檔名相同,只是將其字尾變為 .o。例如,上面的命令將編譯原始碼檔案hellospeak.cpp 並生成物件檔案 hellospeak.o;

下面這條命令將上述兩個原始碼檔案編譯鏈結成乙個單一的可執行程式:

$ g++ hellospeak.cpp speak.cpp -o hellospeak
如果沒有-o和後面的引數,編譯器採用預設的 a.out

本例中就會生成hellospeak 這樣的可執行程式

圖:編譯過程

靜態庫之所以成為【靜態庫】,是因為在鏈結階段,會將彙編生成的目標檔案.o與引用到的庫一起鏈結打包到可執行檔案中。因此對應的鏈結方式稱為靜態鏈結。

試想一下,靜態庫與彙編生成的目標檔案一起鏈結為可執行檔案,那麼靜態庫必定跟.o檔案格式相似。其實乙個靜態庫可以簡單看成是一組目標檔案(.o/.obj檔案)的集合,即很多目標檔案經過壓縮打包後形成的乙個檔案。靜態庫特點總結:

l 靜態庫對函式庫的鏈結是放在編譯時期完成的。

l 程式在執行時與函式庫再無瓜葛,移植方便。

linux下建立與使用靜態庫

linux靜態庫命名規則

linux靜態庫命名規範,必須是"lib[your_library_name].a":lib為字首,中間是靜態庫名,擴充套件名為.a。

建立靜態庫(.a)

通過上面的流程可以知道,linux建立靜態庫過程如下:

l 首先,將**檔案編譯成目標檔案.o(staticmath.o)

g++ -c staticmath.cpp

注意帶引數-c,否則直接編譯為可執行檔案

l 然後,通過ar工具將目標檔案打包成.a靜態庫檔案

ar -crv libstaticmath.a staticmath.o

生成靜態庫libstaticmath.a

-------------------------------分割線------------------------

動態庫通過上面的介紹發現靜態庫,容易使用和理解,也達到了**復用的目的,那為什麼還需要動態庫呢?

為什麼還需要動態庫?

為什麼需要動態庫,其實也是靜態庫的特點導致。

l 空間浪費是靜態庫的乙個問題。

動態庫在程式編譯時並不會被連線到目標**中,而是在程式執行是才被載入。不同的應用程式如果呼叫相同的庫,那麼在記憶體裡只需要有乙份該共享庫的例項,規避了空間浪費問題。動態庫在程式執行是才被載入,也解決了靜態庫對程式的更新、部署和發布頁會帶來麻煩。使用者只需要更新動態庫即可,增量更新

動態庫特點總結:

l 動態庫把對一些庫函式的鏈結載入推遲到程式執行的時期。

l 可以實現程序之間的資源共享。(因此動態庫也稱為共享庫)

l 將一些程式公升級變得簡單。

l 甚至可以真正做到鏈結載入完全由程式設計師在程式**中控制(顯示呼叫)。

window與linux執行檔案格式不同,在建立動態庫的時候有一些差異。

l 在windows系統下的執行檔案格式是pe格式,動態庫需要乙個dllmain函式做出初始化的入口,通常在匯出函式的宣告時需要有_declspec(dllexport)關鍵字

l linux下gcc編譯的執行檔案預設是elf格式,不需要初始化入口,亦不需要函式做特別的宣告,編寫比較方便。

與建立靜態庫不同的是,不需要打包工具(ar、lib.exe),直接使用編譯器即可建立動態庫。

linux中的動態鏈結庫和靜態鏈結庫

什麼是庫?庫是寫好的現有的,成熟的,可以復用的 現實中每個程式都要依賴很多基礎的底層庫,不可能每個人的 都從零開始,因此庫的存在意義非同尋常。本質上來說庫是一種可執行 的二進位制形式,可以被作業系統載入記憶體執行。庫有兩種 靜態庫 a lib 和動態庫 so dll windows上對應的是.lib...

動態鏈結庫和靜態鏈結庫

函式和資料被編譯進乙個二進位制檔案 通常擴充套件名為.lib 在使用靜態庫的情況下,在編譯鏈結可執行檔案時,鏈結器從庫中複製這些函式和資料並把它們和應用程式的其它模組組合起來建立最終的可執行檔案 exe檔案 在使用動態鏈結庫的時候,往往提供兩個檔案 乙個引入庫和乙個dll。引入庫包含被dll匯出的函...

Linux下動態鏈結庫和靜態鏈結庫

第一部分 編譯過程 預處理過程,負責標頭檔案展開,巨集替換,條件編譯的選擇,刪除注釋等工作。gcc e表示進行預處理。編譯過程,負載將預處理生成的檔案,經過詞法分析,語法分析,語義分析及優化後生成彙編檔案。gcc s表示進行編譯。彙編,是將彙編 轉換為機器可執行指令的過程。通過使用gcc c或者as...