隨著Linux性能的不斷提升和逐漸普及,會有越來越多的人在Linux下從事應用軟件的開發。這裡筆者根據從事Linux應用程序開發的經驗,介紹Linux編程庫使用的一些基礎知識。
庫的定義和種類
所謂編程庫就是指始終可以被多個Linux軟件項目重復使用的代碼集。庫是Linux軟件開發所追求的目標,C語言就是一個例子,它包含了幾百個可以重復使用的例程和調試程序的工具代碼,其中包括函數。如果每次編寫新程序都要重新寫這些函數會感到非常麻煩。
使用編程庫有兩個主要優點,一是可以簡化編程,實現代碼重復使用;二是可以直接使用許多經過調試的測試和調試工具。
Linux下的庫文件分為共享庫和靜態庫兩大類,它們兩者的差別僅在程序執行時所需的代碼是在運行時動態加載的,還是在編譯時靜態加載的。
Linux的庫一般在/lib或/usr/lib目錄下。lib是庫(Library)的英文縮寫,它主要存放系統的鏈接庫文件,沒有該目錄則系統就無法正常運行。/lib目錄中存儲著程序運行時使用的共享庫。通過共享庫,許多程序可以重復使用相同的代碼,並且這些庫可以存儲在一個公共的位置上,因此能減小運行程序的大小。這個目錄包含程序在鏈接時使用的各種庫。圖1是筆者/usr/lib(Red Hat Linux 9.0)目錄快照。
圖1 /usr/lib目錄快照
區分庫類型最好的方法是看它們的文件後綴,通常共享庫以.so(Shared Object的縮寫)結尾,靜態鏈接庫通常以.a結尾(Archive的縮寫)。在終端缺省情況下,共享庫通常為綠色,而靜態庫為黑色。
庫的命名和編號
在Linux下開發應用程序時,絕大多數情況使用的都是C語言,目前Linux下最常用的C語言編譯器是GCC,它的全稱是GNU Compiler Collection,下文中的庫介紹都以它為例。
GCC是直接建立在內核基礎上的,是Linux操作系統外層的圖形界面開發工具(Qt、GTK+)和網絡應用開發工具(PHP、Prel、Python)的基礎和過渡。掌握了底層開發工具,可以加快和優化外層應用開發,從而達到開發速度和開發質量的和諧統一。
Glibc 2.3.2是最新版的GNU C庫。它目前不需要修改就可以在GNU Hurd、Linux i386、m68k,以及Alpha系統上執行,並且從2.1版開始加入了對Linux PowerPC、MIPS、Sparc、Sparc 64等系統的支持。
如果想查看自己Linux計算機的Glibc版本可以使用下面命令:
rpm -qa|grep glibc
glibc-common-2.3.2-11.9
glibc-2.3.2-11.9
glibc-devel-2.3.2-11.9
由上可見,Red Hat Linux 9.0使用的Glibc版本是2.3.2。
1.庫的命名
庫的命名比較簡單,第一個特點是所有的庫以lib開頭,GCC命令在在-l選項所指定的文件名前會自動加入lib。第二個特點文件名以.a結尾的庫是靜態庫。第三個特點文件名是.so的庫為共享庫。默認情況下,GCC在鏈接時優先使用共享庫,只有當共享庫不存在時才考慮使用靜態庫。
2.庫的編號
庫的編號格式如下:
library_name.major.num.minor_.min.pathch_num
例如,筆者Red Hat Linux 9.0的GUN數據庫是libgdbm.so.0.0.2,詳細表述如下:
◆library_name是libc.so(標准C庫);
◆major_num是2(主版本號);
◆minor_.min是0(次版本號);
◆pathch_num是0(補丁級別號又稱發行號)。
libgdbm.so.0.0.2所在目錄是/usr/lib,其大小是24576字節,這是一個ELF(Executable and Linking Format)格式的二進制格式文件,運行時由系統將其裝入內存開始執行。
ELF有三種主要類型:
◆適於連接的可重定位文件(Relocatable File),可與其它目標文件一起創建可執行文件和共享目標文件。
◆適於執行的可執行文件(Executable File),用於提供程序的進程映像,加載的內存執行。
◆共享目標文件(Shared Object File),連接器可將它與其它可重定位文件和共享目標文件連接成其它的目標文件;動態連接器又可將它與可執行文件和其它共享目標文件結合起來創建一個進程映像。
常用的編程庫
庫操作命令
Linux庫操作可以使用命令完成,目前常用的命令是ldd和ldconfig。
1.ldd ldd是Library Dependency Display縮寫,它的作用是顯示一個可執行程序必須使用的共享庫。
(1)命令格式
ldd [選項] 文件名
(2)主要參數
-d 執行重定位並報告丟失的函數。
-r 執行對函數和數據對象的重定位,並報告丟失的函數和數據對象。
(3)應用實例
Perl語言是開發者喜歡使用的一種“膠水語言”(能夠將許多元素連接在一起,因此它具有極強的適應性),如果需要查詢有哪些共享庫,則可以首先使用find命令查詢這個程序的絕對路徑,然後使用ldd命令:
#find -name perl
ldd /usr/bin/perl
其結果見圖2所示。圖2中,箭頭左邊的一列顯示的是Prel語言所需的.so文件名, 箭頭右邊的一列顯示是庫的真實庫名稱。應用程序鏈接到庫的so名字是到實際庫的符號鏈接。以第二行為例,最後的0x40014000是庫libperl.so的加載地址。由此可以看到,運行Perl語言需要9個共享庫。
圖2 運行Perl語言需要的共享庫