Linux 中的动态链接库和静态链接库是干什么的?
link
什么是庫?
庫是寫好的現有的,成熟的,可以復用的代碼。現實中每個程序都要依賴很多基礎的底層庫,不可能每個人的代碼都從零開始,因此庫的存在意義非同尋常。
本質上來說庫是一種可執行代碼的二進制形式,可以被操作系統載入內存執行。庫有兩種:靜態庫(.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 程序在運行時與函數庫再無瓜葛,移植方便。
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 空間浪費是靜態庫的一個問題。
另一個問題是靜態庫對程序的更新、部署和發布頁會帶來麻煩。如果靜態庫liba.lib更新了,所以使用它的應用程序都需要重新編譯、發布給用戶(對于玩家來說,可能是一個很小的改動,卻導致整個程序重新下載,全量更新)。
動態庫在程序編譯時并不會被連接到目標代碼中,而是在程序運行是才被載入。不同的應用程序如果調用相同的庫,那么在內存里只需要有一份該共享庫的實例,規避了空間浪費問題。動態庫在程序運行是才被載入,也解決了靜態庫對程序的更新、部署和發布頁會帶來麻煩。用戶只需要更新動態庫即可,增量更新。
動態庫特點總結:
l 動態庫把對一些庫函數的鏈接載入推遲到程序運行的時期。
l 可以實現進程之間的資源共享。(因此動態庫也稱為共享庫)
l 將一些程序升級變得簡單。
l 甚至可以真正做到鏈接載入完全由程序員在程序代碼中控制(顯示調用)。
Window與Linux執行文件格式不同,在創建動態庫的時候有一些差異。
l 在Windows系統下的執行文件格式是PE格式,動態庫需要一個DllMain函數做出初始化的入口,通常在導出函數的聲明時需要有_declspec(dllexport)關鍵字。
l Linux下gcc編譯的執行文件默認是ELF格式,不需要初始化入口,亦不需要函數做特別的聲明,編寫比較方便。
與創建靜態庫不同的是,不需要打包工具(ar、lib.exe),直接使用編譯器即可創建動態庫
總結
以上是生活随笔為你收集整理的Linux 中的动态链接库和静态链接库是干什么的?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux可执行文件如何装载进虚拟内存
- 下一篇: Linux 下的动态链接库问题