Linux 之三 静态库及动态库的编写和使用
??最近在整理舊電腦時,發(fā)現(xiàn)了一些剛?cè)胄袝r的學(xué)習(xí)記錄,以及最早使用新浪博客 http://blog.sina.com.cn/zcshou 寫的一些文章。最近要重拾 Linux,所以把這些 Word 文檔重新排版轉(zhuǎn)到此博客上,一來復(fù)習(xí)一下,二來在 CSDN 上作個存檔!
至于新浪博客上的文章就留那里吧!話說新浪博客是不是塊倒閉了?還有一點(diǎn),如果沒記錯,文章里使用的是 CentOS。
??注意,這些文章里的內(nèi)容多數(shù)可能來自網(wǎng)絡(luò)(當(dāng)初學(xué)習(xí)時翻看了各種網(wǎng)絡(luò)資料)但應(yīng)該不是原版抄襲(作為一名工科生,不動手實踐怎么能行!)。如果您發(fā)現(xiàn)其中內(nèi)容有侵權(quán),請私信我,我將立刻處理!
ELF 文件規(guī)范
??ELF(Executable and Linking Format)是一個二進(jìn)制文件規(guī)范。用于定義不同類型的對象文件(Object files)中都放了什么東西、以及都以什么樣的格式去放這些東西。
??現(xiàn)在流行的二進(jìn)制可執(zhí)行文件格式 (Executable File Format),主要是 Windows 下的 PE(Portable Executable)和 Linux 的 ELF(Executable and Linking Format)可執(zhí)行和鏈接格式)。他們都是 COFF(Common Object File Format)的變種。ARM 體系中采用的也是 ELF 文件格式。
??COFF 是在 Unix System V Release 3 時由 UNIX 系統(tǒng)實驗室(UNIX System Laboratories, USL)首先提出并且使用的文件規(guī)范,后來微軟公司基于 COFF 格式,制定了 PE 格式標(biāo)準(zhǔn),并將其用于當(dāng)時的 Windows NT 系統(tǒng)。在 System V Release 4 時,UNIX 系統(tǒng)實驗室在 COFF 的基礎(chǔ)上,開發(fā)和發(fā)布了 ELF 格式,作為應(yīng)用程序二進(jìn)制接口 (Application Binary Interface,ABI)。
??此后,工具接口標(biāo)準(zhǔn)委員會(Tool Interface Standard Committee,TISC)選擇了正在發(fā)展中的 ELF 標(biāo)準(zhǔn)作為工作在 32 位 INTEL 體系上不同操作系統(tǒng)之間可移植的二進(jìn)制文件格式??梢詮倪@里 找到詳細(xì)的標(biāo)準(zhǔn)文檔。如下圖:
TISC 共出過兩個版本(v1.1和 v1.2)的標(biāo)準(zhǔn)文檔。兩個版本內(nèi)容上差不多,但 v1.2 版本重新組織了原本在 v1.1 版本中的內(nèi)容。可讀性更高。兩個版本的目錄如下所示:
在 ELF 文件規(guī)范中,把系統(tǒng)中采用 ELF 格式的文件(規(guī)范中稱為對象文件(Object File))歸類為以下三種:
- 可重定位文件(Relocatable File ): 這類文件包含代碼和數(shù)據(jù),可用來連接成可執(zhí)行文件或共享對象文件(Object File),靜態(tài)鏈接庫歸為此類,對應(yīng)于 Linux 中的 .o ;Windows 的 .obj.
- 可執(zhí)行文件(Executable File ): 這類文件包含了可以直接執(zhí)行的程序,它的代表就是 ELF 可執(zhí)行文件。Linux 下,他們一般沒有擴(kuò)展名,比如 /bin/bash;Windows 下的 .exe
- 共享對象文件(Object File)(Shared Object File ): 這種文件包含代碼和數(shù)據(jù),鏈接器可以使用這種文件跟其他可重定位文件的共享對象文件(Object File)鏈接,產(chǎn)生新的對象文件(Object File)。對應(yīng)于Linux 中的 .so,Windows 中的 DLL
另外是動態(tài)鏈接器可以將幾個這種共享對象文件(Object File)與可執(zhí)行文件結(jié)合,作為進(jìn)程鏡像文件來運(yùn)行。
??在 Linux 系統(tǒng)中,還有一類文件,被稱為核心轉(zhuǎn)儲文件(Core Dump File) ,當(dāng)進(jìn)程意外終止,系統(tǒng)可以將該進(jìn)程地址空間的內(nèi)容及終止時的一些信息轉(zhuǎn)存到核心轉(zhuǎn)儲文件。 對應(yīng) Linux 下的 core dump。
庫文件
??為了避免一些重復(fù)性的工作并且便于編程,開發(fā)人員定義了一系列的標(biāo)準(zhǔn)函數(shù)以供調(diào)用,這些函數(shù)都放在相應(yīng)的庫中,而我們在進(jìn)行開發(fā)時直接使用這些標(biāo)準(zhǔn)函數(shù)。
??庫文件就是在系統(tǒng)層面對于 ELF 各種文件的稱呼。從本質(zhì)上來說就是一種可執(zhí)行代碼的二進(jìn)制格式,可以被載入內(nèi)存中執(zhí)行。庫分靜態(tài)庫和動態(tài)庫兩種。
靜態(tài)庫
??在編譯目標(biāo)程序時,所使用的靜態(tài)庫中的函數(shù)的所有數(shù)據(jù)都會被整合進(jìn)目標(biāo)代碼中,編譯出的目標(biāo)程序的執(zhí)行程序不需要外部的函數(shù)庫支持。linux 中靜態(tài)庫文件的擴(kuò)展名一般為 .a,a 就是 archive 的縮寫。其編寫步驟很簡單:
編寫最簡單的靜態(tài)庫文件
- myalib.h 文件的內(nèi)容void test();
- myalib.c 文件的內(nèi)容#inlcude <stdio.h> void test() {printf("test\n"); }
說明執(zhí)行成功。
動態(tài)庫
??動態(tài)庫也有的稱為共享庫。在編譯目標(biāo)程序的時候,其使用的動態(tài)函數(shù)庫不會被編譯進(jìn)目標(biāo)程序中,編譯生成的目標(biāo)程序執(zhí)行到相關(guān)函數(shù)時必須要調(diào)用所使用的動態(tài)庫中的對應(yīng)函數(shù)。在 linux 中,動態(tài)庫一般以 .so 結(jié)尾,so 就是 shared object 的縮寫。其基本生成步驟為:
- 隱式調(diào)用:類似于靜態(tài)庫的使用,但需修改動態(tài)鏈接庫的配置文件 /etc/ld.so.conf;
- 顯示調(diào)用:則是在主程序里使用 dlopen、dlsym、dlerror、dlclose 等系統(tǒng)函數(shù)。
編寫最簡單的動態(tài)庫文件
隱式調(diào)用
??隱式調(diào)用的含義是代碼里不出現(xiàn)庫文件名,使用方式和調(diào)用靜態(tài)庫的代碼是類似的。下面我們以一個示例來說明一下。
顯式調(diào)用
??顯式調(diào)用的含義是代碼出現(xiàn)庫文件名,用戶需要自己去打開和管理庫文件。注意以下兩點(diǎn):
下面以示例來說明一下:
參考
??這篇文章中的內(nèi)容,應(yīng)該參考了一篇百度博客。現(xiàn)在百度博客關(guān)閉了,無從查找作者。如果有知道的請私信我,謝謝!
總結(jié)
以上是生活随笔為你收集整理的Linux 之三 静态库及动态库的编写和使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 华大 MCU 之五 SPI 从机 DMA
- 下一篇: 华大 MCU 之六 SEGGER Emb