靜態庫與動態庫實現

2021-08-17 14:49:46 字數 2699 閱讀 9366

本質上來說,庫是一種可執行**的二進位制形式,可以被作業系統載入記憶體執行。某些**需要給別人使用,但是我們不希望別人看到原始碼,就需要以庫的形式進行封裝,只暴露出頭檔案;對於某些不會進行大的改動的**,我們想減少編譯的時間,就可以把它打包成庫。

靜態庫即靜態鏈結庫(windows 下的 .lib,linux 和 mac 下的 .a)。之所以叫做靜態,是因為靜態庫在編譯的時候會被直接拷貝乙份,複製到目標程式裡,這段**在目標程式裡就不會再改變了。

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

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

(3)浪費空間和資源,因為所有相關的目標檔案與牽涉到的函式庫被鏈結合成乙個可執行檔案。

1)linux靜態庫命名規則

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

2)建立靜態庫(.a)

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

再利用ar工具將目標檔案add.o sub.o mul.o div.o打包成靜態庫檔案.a(注意命名規則,我的靜態庫檔名為:libmymath.a)

(2)這樣乙個靜態庫就建立成功了,可以利用 ar -tv libmymath.a命令檢視靜態庫目錄:

(3)linux下使用靜態庫,只需要在編譯的時候,指定靜態庫的搜尋路徑(-l選項)、指定靜態庫名(不需要lib字首和.a字尾,-l選項)。並且執行生成的./a.out 檔案就可以得到結果:

(4)進一步可以刪除靜態函式libmymath.a,然後執行main函式,看看其是否真的鏈結到了目標函式.

動態庫即動態鏈結庫(windows 下的 .dll,linux 下的 .so,mac 下的 .dylib)。與靜態庫相反,動態庫在編譯時並不會被拷貝到目標程式中,目標程式中只會儲存指向動態庫的引用。等到程式執行時,動態庫才會被真正載入進來。

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

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

(3)將一些程式公升級變得簡單。

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

1)linux動態庫的命名規則

動態鏈結庫的名字形式為 lib***.so,字首是lib,字尾名為「.so」。

(1) 針對於實際庫檔案,每個共享庫都有個特殊的名字「soname」。在程式啟動後,程式通過這個名字來告訴動態載入器該載入哪個共享庫。

(2)在檔案系統中,soname僅是乙個鏈結到實際動態庫的鏈結。對於動態庫而言,每個庫實際上都有另乙個名字給編譯器來用。它是乙個指向實際庫映象檔案的鏈結檔案(lib+soname+.so)。

2)生成動態庫

shared:表示生成共享庫格式

fpic:產生位置無關碼(position independent code)

一般生成動態庫有兩步:

(1)生成目標檔案,此時要加編譯器選項-fpic。【ps:-fpic是建立與地質無關的編譯程式,是為了能夠在多個應用程式間共享】

(2)生成動態庫,此時要加鏈結器選項-shared。【ps:-shared是指定生成動態鏈結庫】

3)例項

按照動態庫生成步驟,就生成了libmymath.so 動態庫檔案:

使用動態庫:

l:鏈結動態庫,只要庫名即可(去掉lib及版本號)

l:鏈結庫所在路徑

執行動態庫

1、拷貝.so檔案到系統共享路徑下,一般指/usr/lib

2、更改ld_library_path

刪除動態庫

當動態庫檔案被刪除時,執行main,執行失敗,說明程式在執行的時候才鏈結動態庫的**

二者的不同點在於**被載入的時刻不同

(1)靜態庫在程式編譯時會被連線到目標**中,程式執行時將不再需要該靜態庫,因此體積較大

(2)動態庫在程式編譯時並不會被連線到目標**中,而是在程式執行是才被載入,因此在程式執行時還需要動態庫存在,因此**體積較小。  

靜態庫 動態庫 實現與區別

程式在編譯鏈結的時候把庫的 鏈結到可執行檔案中。程式執行的時候將不再需要靜態庫,windows下 lib 程式在執行的時候才去鏈結動態庫的 多個程式共享使用庫的 乙個與動態庫鏈結的可執行檔案僅僅包含它用到的函式入口位址的乙個表,而不是外部函式所在目標檔案的整個機器碼,windows下 dll 生成 ...

靜態庫與動態庫

linux下靜態庫 a 的例子 mylib.h 位於include資料夾下 ifndef mylib h define mylib h int add int a,int b endif mylib.cpp 位於lib資料夾中 include mylib.h int add int a,int b ...

靜態庫與動態庫

庫本質上是一種可執行的二進位制 可以被作業系統載入 linux和windows的庫是不相容的 庫可以分為靜態塊和動態庫,二者的不同點在於 被載入的時刻不同。靜態庫 在程式編譯時會被連線到目標 中,程式執行時不再需要改靜態庫,體積較大,一般應用與移植過程中在宿主機上編譯的 靜態庫檔名的命名規範是以li...