LINUX動(dòng)態(tài)鏈接庫的創(chuàng)建與使用教學(xué)文案_第1頁
LINUX動(dòng)態(tài)鏈接庫的創(chuàng)建與使用教學(xué)文案_第2頁
LINUX動(dòng)態(tài)鏈接庫的創(chuàng)建與使用教學(xué)文案_第3頁
LINUX動(dòng)態(tài)鏈接庫的創(chuàng)建與使用教學(xué)文案_第4頁
LINUX動(dòng)態(tài)鏈接庫的創(chuàng)建與使用教學(xué)文案_第5頁
已閱讀5頁,還剩40頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、Good is good, but better carries it.精益求精,善益求善。LINUX動(dòng)態(tài)鏈接庫的創(chuàng)建與使用-一,LINUX系統(tǒng)中動(dòng)態(tài)鏈接庫的創(chuàng)建與使用大家都知道,在WINDOWS系統(tǒng)中有很多的動(dòng)態(tài)鏈接庫(以.DLL為后綴的文件,DLL即DynamicLinkLibrary)。這種動(dòng)態(tài)鏈接庫,和靜態(tài)函數(shù)庫不同,它里面的函數(shù)并不是執(zhí)行程序本身的一部分,而是根據(jù)執(zhí)行程序需要按需裝入,同時(shí)其執(zhí)行代碼可在多個(gè)執(zhí)行程序間共享,節(jié)省了空間,提高了效率,具備很高的靈活性,得到越來越多程序員和用戶的青睞。那么,在LINUX系統(tǒng)中有無這樣的函數(shù)庫呢?答案是肯定的,LINUX的動(dòng)態(tài)鏈接庫不僅有,而

2、且為數(shù)不少。在/lib目錄下,就有許多以.so作后綴的文件,這就是LINUX系統(tǒng)應(yīng)用的動(dòng)態(tài)鏈接庫,只不過與WINDOWS叫法不同,它叫so,即SharedObject,共享對象。(在LINUX下,靜態(tài)函數(shù)庫是以.a作后綴的)X-WINDOW作為LINUX下的標(biāo)準(zhǔn)圖形窗口界面,它本身就采用了很多的動(dòng)態(tài)鏈接庫(在/usr/X11R6/lib目錄下),以方便程序間的共享,節(jié)省占用空間。著名的APACHE網(wǎng)頁服務(wù)器,也采用了動(dòng)態(tài)鏈接庫,以便擴(kuò)充程序功能。你只需將PHP動(dòng)態(tài)鏈接庫拷到其共享目錄,修改一下配置,APACHE就可以支持PHP網(wǎng)頁了。如果你愿意,可以自己編寫動(dòng)態(tài)鏈接庫,讓APACHE支持你自己

3、定義的網(wǎng)頁格式。這就是動(dòng)態(tài)鏈接的好處。1、LINUX下動(dòng)態(tài)鏈接庫的創(chuàng)建在LINUX系統(tǒng)下,創(chuàng)建動(dòng)態(tài)鏈接庫是件再簡單不過的事情。只要在編譯函數(shù)庫源程序時(shí)加上-shared選項(xiàng)即可,這樣所生成的執(zhí)行程序即為動(dòng)態(tài)鏈接庫。從某種意義上來說,動(dòng)態(tài)鏈接庫也是一種執(zhí)行程序。按一般規(guī)則,程序名應(yīng)帶.so后綴。下面舉個(gè)例子說說。我準(zhǔn)備編寫兩個(gè)函數(shù),一個(gè)用于查詢當(dāng)前日期getdate,一個(gè)用于查詢當(dāng)前時(shí)間gettime,并將這兩個(gè)函數(shù)存于動(dòng)態(tài)鏈接庫my.so中。為此,需要做以下幾項(xiàng)工作。1.1編寫用戶接口文件datetime.h,內(nèi)容如下(每行前面的數(shù)字為行號):-1/*datetime.h:縱橫軟件制作中心雨亦

4、奇編寫,2001-06-28.*/23#ifndef_DATETIME_H45#define_DATETIME_H67/*日期結(jié)構(gòu)*/8typedefstruct910intyear;11intmon;12intday;13DATETYPE;1415/*時(shí)間結(jié)構(gòu)*/16typedefstruct1718charhour;19charmin;20charsec;21TIMETYPE;2223/*函數(shù)原型說明*/2425#ifdefSHARED26int(*getdate)(DATETYPE*d);27#else28intgetdate(DATETYPE*d);29#endif3031#ifdef

5、SHARED32int(*gettime)(TIMETYPE*t);33#else34intgettime(TIMETYPE*t);35#endif3637#endif38-這個(gè)用戶接口文件中,先定義了日期與時(shí)間結(jié)構(gòu),接著定義一下函數(shù)的原型。動(dòng)態(tài)函數(shù)與靜態(tài)函數(shù)的原型說明不同的是,動(dòng)態(tài)函數(shù)應(yīng)使用(*函數(shù)名)的形式,以便引用其指針。若要引用文件中的動(dòng)態(tài)函數(shù)說明,用戶應(yīng)該定義一下SHARED宏,這樣才能使用。1.2編寫getdate.c,源程序如下:-1/*getdate.c:縱橫軟件制作中心雨亦奇編寫,2001-06-28.*/23#includetime.h4#includedatetime.h

6、56intgetdate(DATETYPE*d)78longti;9structtm*tm;1011time(&ti);12tm=localtime(&ti);13d-year=tm-tm_year+1900;14d-mon=tm-tm_mon+1;15d-day=tm-tm_mday;1617-在getdate函數(shù)中,先調(diào)用time取得以秒計(jì)的系統(tǒng)時(shí)間,再用localtime函數(shù)轉(zhuǎn)換一下時(shí)間結(jié)構(gòu),最后調(diào)整得到正確的日期。1.3編寫gettime.c,源程序如下:-1/*gettime.c:縱橫軟件制作中心雨亦奇編寫,2001-06-28.*/23#includetime.h4#include

7、datetime.h56intgettime(TIMETYPE*t)78longti;9structtm*tm;1011time(&ti);12tm=localtime(&ti);13t-hour=tm-tm_hour;14t-min=tm-tm_min;15t-sec=tm-tm_sec;1617-gettime函數(shù)與getdate函數(shù)相仿,先用time函數(shù)取得以秒計(jì)的系統(tǒng)時(shí)間,再用localtime函數(shù)轉(zhuǎn)換一下時(shí)間結(jié)構(gòu),最后返回當(dāng)前的時(shí)間(不需調(diào)整)。1.4編寫維護(hù)文件makefile-lib,內(nèi)容如下:-1#makefile-lib:縱橫軟件制作中心雨亦奇編寫,2001-06-28.23

8、all:my.so45SRC=getdate.cgettime.c67TGT=$(SRC:.c=.o)89$(SRC):datetime.h10touch$1112%.o:%.c13cc-c$?1415#動(dòng)態(tài)函數(shù)庫(my.so)生成16my.so:$(TGT)17cc-shared-o$(TGT)18-編寫維護(hù)文件的目的,在于方便程序員維護(hù)程序,尤其是維護(hù)比較大的工程項(xiàng)目。一個(gè)素質(zhì)良好的程序員應(yīng)該學(xué)會(huì)熟練地編寫維護(hù)文件makefile。定義了文件間的依賴關(guān)系后,一旦源文件發(fā)生變化,僅需make一下,其目標(biāo)文件維護(hù)代碼會(huì)自動(dòng)執(zhí)行,從而自動(dòng)更新目標(biāo)文件,減少了許多工作量。注意:每行維護(hù)代碼必須以T

9、AB(跳格鍵)開始,不是的話make時(shí)將出錯(cuò)。本維護(hù)文件第1行是注釋行,以#號開頭;文件第3行定義所有需要維護(hù)的函數(shù)庫;第5行定義相關(guān)源程序文件;第7行定義目標(biāo)文件;第9-10行說明所有源程序依賴于datetime.h頭文件,并有相應(yīng)維護(hù)代碼,即touch一下,更新一下源文件的時(shí)間;第12-13行定義.o文件依賴于相應(yīng)的.c文件,并指定了維護(hù)代碼,即用cc編譯一下;第16-17行定義共享庫my.so依賴的目標(biāo)文件,維護(hù)代碼中用-shared編譯選項(xiàng),以生成動(dòng)態(tài)鏈接庫my.so。1.5運(yùn)行make-fmakefile-lib命令make運(yùn)行后,動(dòng)態(tài)鏈接庫my.so就產(chǎn)生了,我們就可以在程序中調(diào)用

10、了。如果想讓系統(tǒng)所有用戶都可以使用,則應(yīng)以root用戶登錄系統(tǒng),將這個(gè)庫拷貝到/lib目錄下(命令:cpmy.so/lib),或者在/lib目錄下建個(gè)符號連接即可(命令:ln-spwd/my.so/lib)。2、LINUX下動(dòng)態(tài)鏈接庫的使用2.1重要的dlfcn.h頭文件LINUX下使用動(dòng)態(tài)鏈接庫,源程序需要包含dlfcn.h頭文件,此文件定義了調(diào)用動(dòng)態(tài)鏈接庫的函數(shù)的原型。下面詳細(xì)說明一下這些函數(shù)。2.1.1dlerror原型為:constchar*dlerror(void);當(dāng)動(dòng)態(tài)鏈接庫操作函數(shù)執(zhí)行失敗時(shí),dlerror可以返回出錯(cuò)信息,返回值為NULL時(shí)表示操作函數(shù)執(zhí)行成功。2.1.2dl

11、open原型為:void*dlopen(constchar*filename,intflag);dlopen用于打開指定名字(filename)的動(dòng)態(tài)鏈接庫,并返回操作句柄。filename:如果名字不以/開頭,則非絕對路徑名,將按下列先后順序查找該文件。(1)用戶環(huán)境變量中的LD_LIBRARY值;(2)動(dòng)態(tài)鏈接緩沖文件/etc/ld.so.cache(3)目錄/lib,/usr/libflag表示在什么時(shí)候解決未定義的符號(調(diào)用)。取值有兩個(gè):1)RTLD_LAZY:表明在動(dòng)態(tài)鏈接庫的函數(shù)代碼執(zhí)行時(shí)解決。2)RTLD_NOW:表明在dlopen返回前就解決所有未定義的符號,一旦未解決,dl

12、open將返回錯(cuò)誤。dlopen調(diào)用失敗時(shí),將返回NULL值,否則返回的是操作句柄。2.1.3dlsym:取函數(shù)執(zhí)行地址原型為:void*dlsym(void*handle,char*symbol);dlsym根據(jù)動(dòng)態(tài)鏈接庫操作句柄(handle)與符號(symbol),返回符號對應(yīng)的函數(shù)的執(zhí)行代碼地址。由此地址,可以帶參數(shù)執(zhí)行相應(yīng)的函數(shù)。如程序代碼:void(*add)(intx,inty);/*說明一下要調(diào)用的動(dòng)態(tài)函數(shù)add*/add=dlsym(xxx.so,add);/*打開xxx.so共享庫,取add函數(shù)地址*/add(89,369);/*帶兩個(gè)參數(shù)89和369調(diào)用add函數(shù)*/2.

13、1.4dlclose:關(guān)閉動(dòng)態(tài)鏈接庫原型為:intdlclose(void*handle);dlclose用于關(guān)閉指定句柄的動(dòng)態(tài)鏈接庫,只有當(dāng)此動(dòng)態(tài)鏈接庫的使用計(jì)數(shù)為0時(shí),才會(huì)真正被系統(tǒng)卸載。2.2在程序中使用動(dòng)態(tài)鏈接庫函數(shù)2.2.1程序范例下面的程序裝載了動(dòng)態(tài)鏈接庫my.so,并用getdate,gettime取得當(dāng)前日期與時(shí)間后輸出。-1/*/2/*文件名稱:dy.c*/3/*功能描述:動(dòng)態(tài)鏈接庫應(yīng)用示范程序*/4/*程序編寫:縱橫軟件制作中心雨亦奇*/5/*編寫時(shí)間:2001-06-28*/6/*/78#includestdio.h/*包含標(biāo)準(zhǔn)輸入輸出文件*/910#includedlf

14、cn.h/*包含動(dòng)態(tài)鏈接功能接口文件*/11#defineSOFILE./my.so/*指定動(dòng)態(tài)鏈接庫名稱*/1213#defineSHARED/*定義宏,確認(rèn)共享,以便引用動(dòng)態(tài)函數(shù)*/14#includedatetime.h/*包含用戶接口文件*/1516main()1718DATETYPEd;19TIMETYPEt;20void*dp;21char*error;2223puts(動(dòng)態(tài)鏈接庫應(yīng)用示范);2425dp=dlopen(SOFILE,RTLD_LAZY);/*打開動(dòng)態(tài)鏈接庫*/2627if(dp=NULL)/*若打開失敗則退出*/2829fputs(dlerror(),stderr

15、);30exit(1);313233getdate=dlsym(dp,getdate);/*定位取日期函數(shù)*/3435error=dlerror();/*檢測錯(cuò)誤*/36if(error)/*若出錯(cuò)則退出*/3738fputs(error,stderr);39exit(1);404142getdate(&d);/*調(diào)用此共享函數(shù)*/43printf(當(dāng)前日期:%04d-%02d-%02dn,d.year,d.mon,d.day);4445gettime=dlsym(dp,gettime);/*定位取時(shí)間函數(shù)*/4647error=dlerror();/*檢測錯(cuò)誤*/48if(error)/*若

16、出錯(cuò)則退出*/4950fputs(error,stderr);51exit(1);525354gettime(&t);/*調(diào)用此共享函數(shù)*/55printf(當(dāng)前時(shí)間:%02d:%02d:%02dn,t.hour,t.min,t.sec);5657dlclose(dp);/*關(guān)閉共享庫*/5859exit(0);/*成功返回*/6061-程序說明:第8行:包含標(biāo)準(zhǔn)輸入輸出頭文件,因?yàn)槌绦蛑惺褂昧藀rintf,puts,fputs等標(biāo)準(zhǔn)輸入輸出函數(shù),需要讓編譯器根據(jù)頭文件中函數(shù)的原型,檢查一下語法;第10-11行:包含動(dòng)態(tài)鏈接庫功能頭文件,并定義動(dòng)態(tài)鏈接庫名稱;第13-14行:定義宏SHARED

17、以便引用14行的頭文件datetime.h中的動(dòng)態(tài)函數(shù)說明;第25行:用dlopen打開SOFILE共享庫,返回句柄dp;第27-31行:檢測dp是否為空,為空則顯示錯(cuò)誤后退出;第33行:用dlsym取得getdate函數(shù)動(dòng)態(tài)地址;第35-40行:如果dlerror返回值不為空,則dlsym執(zhí)行出錯(cuò),程序顯示錯(cuò)誤后退出;第42-43行:執(zhí)行g(shù)etdate調(diào)用,輸出當(dāng)前日期;第45行:用dlsym取得gettime函數(shù)動(dòng)態(tài)地址;第47-52行:如果dlerror返回值不為空,則dlsym執(zhí)行出錯(cuò),程序顯示錯(cuò)誤后退出;第54-55行:執(zhí)行g(shù)ettime調(diào)用,輸出當(dāng)前時(shí)間;第57行:用dlclose

18、關(guān)閉dp所指示的動(dòng)態(tài)鏈接庫;第59行:程序退出,返回0值。2.2.2編寫維護(hù)文件維護(hù)文件makefile內(nèi)容如下:-1#makefile:縱橫軟件制作中心雨亦奇編寫,2001-06-28.23all:dy45DYSRC=dy.c67DYTGT=$(DYSRC:.c=.o)89%.o:%.c10cc-c$?1112#動(dòng)態(tài)庫應(yīng)用示范程序13dy:$(DYTGT)14cc-rdynamic-s-o$(DYTGT)-ldl15-維護(hù)文件說明:第3行:定義所有需要維護(hù)的模塊;第5行:定義源程序;第7行:定義目標(biāo)文件;第9-10行:定義.o文件依賴于.c文件,維護(hù)代碼為“cc-c變動(dòng)的源文件名”;第13-

19、14行:定義dy依賴于變量DYTGT指示的值,維護(hù)代碼中采用-rdynamic選項(xiàng)以指定輸出文件為動(dòng)態(tài)鏈接的方式,選項(xiàng)-s指定刪除目標(biāo)文件中的符號表,最后的選項(xiàng)-ldl則指示裝配程序ld需要裝載dl函數(shù)庫。2.2.3運(yùn)行make命令運(yùn)行make后將產(chǎn)生執(zhí)行文件dy,運(yùn)行后將產(chǎn)生如下類似信息:動(dòng)態(tài)鏈接庫應(yīng)用示范當(dāng)前日期:2001-06-28當(dāng)前時(shí)間:10:06:21當(dāng)刪除my.so文件時(shí),將出現(xiàn)以下信息:動(dòng)態(tài)鏈接庫應(yīng)用示范my.so:cannotopensharedobjectfile:文件或目錄不存在3、小結(jié)LINUX創(chuàng)建與使用動(dòng)態(tài)鏈接庫并不是一件難事。編譯函數(shù)源程序時(shí)選用-shared選項(xiàng)即

20、可創(chuàng)建動(dòng)態(tài)鏈接庫,注意應(yīng)以.so后綴命名,最好放到公用庫目錄(如/lib,/usr/lib等)下面,并要寫好用戶接口文件,以便其它用戶共享。使用動(dòng)態(tài)鏈接庫,源程序中要包含dlfcn.h頭文件,寫程序時(shí)注意dlopen等函數(shù)的正確調(diào)用,編譯時(shí)要采用-rdynamic選項(xiàng)與-ldl選項(xiàng),以產(chǎn)生可調(diào)用動(dòng)態(tài)鏈接庫的執(zhí)行代碼。二,LINUX動(dòng)態(tài)鏈接庫高級應(yīng)用在LINUX下動(dòng)態(tài)鏈接庫的創(chuàng)建與應(yīng)用一文中,我介紹了LINUX動(dòng)態(tài)鏈接庫的基本知識.其要點(diǎn)是:用戶根據(jù)實(shí)際情況需要,利用dlopen,dlsym,dlclose等動(dòng)態(tài)鏈接庫操作函數(shù),裝入指定的動(dòng)態(tài)鏈接庫中指定的函數(shù),然后加以執(zhí)行.程序中使用很少的動(dòng)態(tài)

21、函數(shù)時(shí),這樣的做法尚可.如果程序需要調(diào)用大量的動(dòng)態(tài)函數(shù),那么采用這樣的編程手段將是非常繁復(fù)的,所以我們必須使用一種更為聰明的辦法,以減少代碼量,提高工作效率.這就是現(xiàn)在我要舉例介紹的LINUX動(dòng)態(tài)鏈接庫高級應(yīng)用.注:本文舉的例子類似上篇文章,只是文件的內(nèi)容已做相應(yīng)修改,裁減了不少.示例程序ady.c和兩個(gè)動(dòng)態(tài)函數(shù)的源程序getdate.c與gettime.c僅修改了頭文件的名字,其內(nèi)容不再列出.本文使用頭文件為adatetime.h.要想高效地應(yīng)用LINUX動(dòng)態(tài)鏈接庫(尤其是用戶自己編寫的),需要做以下工作:一、編寫合格的動(dòng)態(tài)鏈接庫頭文件C語言的頭文件,可供一個(gè)或多個(gè)程序引用,里面一般定義程序

22、所需的常量,自定義類型及函數(shù)原型說明等.其中的函數(shù)原型說明,則供編譯器檢查語法,用于排除引用參數(shù)時(shí)類型不一致的錯(cuò)誤.只有編寫合格的動(dòng)態(tài)鏈接庫頭文件,程序員才能正確使用動(dòng)態(tài)鏈接庫內(nèi)的函數(shù).動(dòng)態(tài)鏈接庫頭文件要采用C語言標(biāo)準(zhǔn)格式,其中的動(dòng)態(tài)函數(shù)原型定義,不必象上文介紹的那樣用(*動(dòng)態(tài)函數(shù)名)的描述形式.請看下面的例子:(每行開始的數(shù)字為所在行行號,為筆者添加,供注解使用)1/*adatetime.h:縱橫軟件制作中心雨亦奇()編寫,2002-03-06.*/23#ifndef_DATETIME_H45#define_DATETIME_H67/*日期結(jié)構(gòu)*/8typedefstruct910intye

23、ar;11intmon;12intday;13DATETYPE;1415/*時(shí)間結(jié)構(gòu)*/16typedefstruct1718charhour;19charmin;20charsec;21TIMETYPE;2223intgetdate(DATETYPE*d);/*取當(dāng)前日期*/24intgettime(TIMETYPE*t);/*取當(dāng)前時(shí)間*/2526#endif27注:與上文的datetime.h文件比較,從該頭文件第23,24行可以看到,動(dòng)態(tài)函數(shù)getdate,gettime的原型定義改變了,不再使用(*getdate),(*gettime)的格式了(這種格式使用較為羅嗦).二、正確編譯與

24、命名動(dòng)態(tài)鏈接庫為了讓GCC編譯器生成動(dòng)態(tài)鏈接庫,編譯時(shí)須加選項(xiàng)-shared.(這點(diǎn)須牢記)LINUX系統(tǒng)中,為了讓動(dòng)態(tài)鏈接庫能被系統(tǒng)中其它程序共享,其名字應(yīng)符合“l(fā)ib*.so*”這種格式.如果某個(gè)動(dòng)態(tài)鏈接庫不符合此格式,則LINUX的動(dòng)態(tài)鏈接庫自動(dòng)裝入程序(ld.so)將搜索不到此鏈接庫,其它程序也無法共享之.格式中,第一個(gè)*通常表示為簡寫的庫名,第二個(gè)*通常表示為該庫的版本號.如:在我的系統(tǒng)中,基本C動(dòng)態(tài)鏈接庫的名字為libc.so.6,線程pthread動(dòng)態(tài)鏈接庫的名字為libpthread.so.0等等.本文例子所生成的動(dòng)態(tài)鏈接庫的名字為libmy.so,雖沒有版本號,但也符合所要求

25、的格式.生成該動(dòng)態(tài)鏈接庫的維護(hù)文件makefile-lib內(nèi)容如下:1#makefile:縱橫軟件制作中心雨亦奇編寫,2002-03-07.23all:libmy.so45SRC=getdate.cgettime.c67TGT=$(SRC:.c=.o)89$(SRC):adatetime.h10touch$1112%.o:%.c13cc-c$?1415#動(dòng)態(tài)鏈接庫(libmy.so)生成16libmy.so:$(TGT)17cc-s-shared-o$(TGT)18運(yùn)行命令:$make-fmakefile-lib$即生成libmy.so庫.注:維護(hù)文件中,第17行用-shared選項(xiàng)以生成動(dòng)態(tài)

26、鏈接庫,用-s選項(xiàng)以去掉目標(biāo)文件中的符號表,從而減小文件長度.三、共享動(dòng)態(tài)鏈接庫3.1動(dòng)態(tài)鏈接庫配置文件為了讓動(dòng)態(tài)鏈接庫為系統(tǒng)所使用,需要維護(hù)動(dòng)態(tài)鏈接庫的配置文件-/etc/ld.so.conf.此文件內(nèi),存放著可被LINUX共享的動(dòng)態(tài)鏈接庫所在目錄的名字(系統(tǒng)目錄/lib,/usr/lib除外),各個(gè)目錄名間以空白字符(空格,換行等)或冒號或逗號分隔.一般的LINUX發(fā)行版中,此文件均含一個(gè)共享目錄/usr/X11R6/lib,為Xwindow窗口系統(tǒng)的動(dòng)態(tài)鏈接庫所在的目錄.下面看看我的系統(tǒng)中此文件的內(nèi)容如何:#cat/etc/ld.so.conf/usr/X11R6/lib/usr/zzz

27、/lib#由上可以看出,該動(dòng)態(tài)庫配置文件中,增加了一個(gè)/usr/zzz/lib目錄.這是我自己新建的共享庫目錄,下面存放我新開發(fā)的可供系統(tǒng)共享的動(dòng)態(tài)鏈接庫.3.2動(dòng)態(tài)鏈接庫管理命令為了讓動(dòng)態(tài)鏈接庫為系統(tǒng)所共享,還需運(yùn)行動(dòng)態(tài)鏈接庫的管理命令-ldconfig.此執(zhí)行程序存放在/sbin目錄下.ldconfig命令的用途,主要是在默認(rèn)搜尋目錄(/lib和/usr/lib)以及動(dòng)態(tài)庫配置文件/etc/ld.so.conf內(nèi)所列的目錄下,搜索出可共享的動(dòng)態(tài)鏈接庫(格式如前介紹,lib*.so*),進(jìn)而創(chuàng)建出動(dòng)態(tài)裝入程序(ld.so)所需的連接和緩存文件.緩存文件默認(rèn)為/etc/ld.so.cache,

28、此文件保存已排好序的動(dòng)態(tài)鏈接庫名字列表.ldconfig通常在系統(tǒng)啟動(dòng)時(shí)運(yùn)行,而當(dāng)用戶安裝了一個(gè)新的動(dòng)態(tài)鏈接庫時(shí),就需要手工運(yùn)行這個(gè)命令.ldconfig命令行用法如下:ldconfig-v|-verbose-n-N-X-fCONF-CCACHE-rROOT-l-p|-print-cache-cFORMAT-format=FORMAT-V-?|-help|-usagepath.ldconfig可用的選項(xiàng)說明如下:(1)-v或-verbose:用此選項(xiàng)時(shí),ldconfig將顯示正在掃描的目錄及搜索到的動(dòng)態(tài)鏈接庫,還有它所創(chuàng)建的連接的名字.(2)-n:用此選項(xiàng)時(shí),ldconfig僅掃描命令行指定的

29、目錄,不掃描默認(rèn)目錄(/lib,/usr/lib),也不掃描配置文件/etc/ld.so.conf所列的目錄.(3)-N:此選項(xiàng)指示ldconfig不重建緩存文件(/etc/ld.so.cache).若未用-X選項(xiàng),ldconfig照常更新文件的連接.(4)-X:此選項(xiàng)指示ldconfig不更新文件的連接.若未用-N選項(xiàng),則緩存文件正常更新.(5)-fCONF:此選項(xiàng)指定動(dòng)態(tài)鏈接庫的配置文件為CONF,系統(tǒng)默認(rèn)為/etc/ld.so.conf.(6)-CCACHE:此選項(xiàng)指定生成的緩存文件為CACHE,系統(tǒng)默認(rèn)的是/etc/ld.so.cache,此文件存放已排好序的可共享的動(dòng)態(tài)鏈接庫的列表.

30、(7)-rROOT:此選項(xiàng)改變應(yīng)用程序的根目錄為ROOT(是調(diào)用chroot函數(shù)實(shí)現(xiàn)的).選擇此項(xiàng)時(shí),系統(tǒng)默認(rèn)的配置文件/etc/ld.so.conf,實(shí)際對應(yīng)的為ROOT/etc/ld.so.conf.如用-r/usr/zzz時(shí),打開配置文件/etc/ld.so.conf時(shí),實(shí)際打開的是/usr/zzz/etc/ld.so.conf文件.用此選項(xiàng),可以大大增加動(dòng)態(tài)鏈接庫管理的靈活性.(8)-l:通常情況下,ldconfig搜索動(dòng)態(tài)鏈接庫時(shí)將自動(dòng)建立動(dòng)態(tài)鏈接庫的連接.選擇此項(xiàng)時(shí),將進(jìn)入專家模式,需要手工設(shè)置連接.一般用戶不用此項(xiàng).(9)-p或-print-cache:此選項(xiàng)指示ldconfig

31、打印出當(dāng)前緩存文件所保存的所有共享庫的名字.(10)-cFORMAT或-format=FORMAT:此選項(xiàng)用于指定緩存文件所使用的格式,共有三種:old(老格式),new(新格式)和compat(兼容格式,此為默認(rèn)格式).(11)-V:此選項(xiàng)打印出ldconfig的版本信息,而后退出.(12)-?或-help或-usage:這三個(gè)選項(xiàng)作用相同,都是讓ldconfig打印出其幫助信息,而后退出.舉三個(gè)例子:例1:#ldconfig-p793libsfoundincache/etc/ld.so.cachelibzvt.so.2(libc6)=/usr/lib/libzvt.so.2libzvt.s

32、o(libc6)=/usr/lib/libzvt.solibz.so.1.1.3(libc6)=/usr/lib/libz.so.1.1.3libz.so.1(libc6)=/lib/libz.so.1.#注:有時(shí)候用戶想知道系統(tǒng)中有哪些動(dòng)態(tài)鏈接庫,或者想知道系統(tǒng)中有沒有某個(gè)動(dòng)態(tài)鏈接庫,這時(shí),可用-p選項(xiàng)讓ldconfig輸出緩存文件中的動(dòng)態(tài)鏈接庫列表,從而查詢得到.例子中,ldconfig命令的輸出結(jié)果第1行表明在緩存文件/etc/ld.so.cache中找到793個(gè)共享庫,第2行開始便是一系列共享庫的名字及其全名(絕對路徑).因?yàn)閷?shí)際輸出結(jié)果太多,為節(jié)省篇幅,以.表示省略的部分.例2:#l

33、dconfig-v/lib:liby.so.1-liby.so.1libnss_wins.so-libnss_wins.so./usr/lib:libjscript.so.2-libjscript.so.2.0.0libkspell.so.2-libkspell.so.2.0.0./usr/X11R6/lib:libmej-0.8.10.so-libmej-0.8.10.solibXaw3d.so.7-libXaw3d.so.7.0.#注:ldconfig命令在運(yùn)行正常的情況下,默認(rèn)不輸出什么東西.本例中用了-v選項(xiàng),以使ldconfig在運(yùn)行時(shí)輸出正在掃描的目錄及搜索到的共享庫,用戶可以清楚

34、地看到運(yùn)行的結(jié)果.執(zhí)行結(jié)束后,ldconfig將刷新緩存文件/etc/ld.so.cache.例3:#ldconfig/usr/zhsoft/lib#注:當(dāng)用戶在某個(gè)目錄下面創(chuàng)建或拷貝了一個(gè)動(dòng)態(tài)鏈接庫,若想使其被系統(tǒng)共享,可以執(zhí)行一下ldconfig目錄名這個(gè)命令.此命令的功能在于讓ldconfig將指定目錄下的動(dòng)態(tài)鏈接庫被系統(tǒng)共享起來,意即:在緩存文件/etc/ld.so.cache中追加進(jìn)指定目錄下的共享庫.本例讓系統(tǒng)共享了/usr/zhsoft/lib目錄下的動(dòng)態(tài)鏈接庫.需要說明的是,如果此目錄不在/lib,/usr/lib及/etc/ld.so.conf文件所列的目錄里面,則再度運(yùn)行l(wèi)

35、dconfig時(shí),此目錄下的動(dòng)態(tài)鏈接庫可能不被系統(tǒng)共享了.3.3動(dòng)態(tài)鏈接庫如何共享了解了以上知識,我們可以采用以下三種方法來共享動(dòng)態(tài)鏈接庫:(注:均須在超級用戶狀態(tài)下操作,以我的動(dòng)態(tài)鏈接庫libmy.so共享過程為例)(1)拷貝動(dòng)態(tài)鏈接庫到系統(tǒng)共享目錄下,或在系統(tǒng)共享目錄下為該動(dòng)態(tài)鏈接庫建立個(gè)連接(硬連接或符號連接均可,常用符號連接).這里說的系統(tǒng)共享目錄,指的是LINUX動(dòng)態(tài)鏈接庫存放的目錄,它包含/lib,/usr/lib以及/etc/ld.so.conf文件內(nèi)所列的一系列目錄.#cplibmy.so/lib#ldconfig#或:#ln-spwd/libmy.so/lib#ldconfi

36、g#(2)將動(dòng)態(tài)鏈接庫所在目錄名追加到動(dòng)態(tài)鏈接庫配置文件/etc/ld.so.conf中.#pwd/etc/ld.so.conf#ldconfig#(3)利用動(dòng)態(tài)鏈接庫管理命令ldconfig,強(qiáng)制其搜索指定目錄,并更新緩存文件,便于動(dòng)態(tài)裝入.#ldconfigpwd#需要說明的是,這種操作方法雖然有效,但效果是暫時(shí)的,供程序測試還可以,一旦再度運(yùn)行l(wèi)dconfig,則緩存文件內(nèi)容可能改變,所需的動(dòng)態(tài)鏈接庫可能不被系統(tǒng)共享了.與之相比較,前兩種方法是可靠的方法,值得業(yè)已定型的動(dòng)態(tài)鏈接庫共享時(shí)采用.前兩種方法還有一個(gè)特點(diǎn),即最后一條命令都是ldconfig,也即均需要更新一下緩存文件,以確保動(dòng)態(tài)

37、鏈接庫的共享生效.四、含有動(dòng)態(tài)函數(shù)的程序的編譯4.1防止編譯因未指定動(dòng)態(tài)鏈接庫而出錯(cuò)當(dāng)一個(gè)程序使用動(dòng)態(tài)函數(shù)時(shí),編譯該程序時(shí)就必須指定含所用動(dòng)態(tài)函數(shù)的動(dòng)態(tài)鏈接庫,否則編譯將會(huì)出錯(cuò)退出.如本文示例程序ady.c的編譯(未明確引用動(dòng)態(tài)鏈接庫libmy.so):#cc-oadyady.c/tmp/ccL4FsJp.o:Infunctionmain:/tmp/ccL4FsJp.o(.text+0 x43):undefinedreferencetogettimecollect2:ldreturned1exitstatus#注:因?yàn)閍dy.c所含的動(dòng)態(tài)函數(shù)getdate,gettime不在系統(tǒng)函數(shù)庫中,所以

38、連接時(shí)出錯(cuò).4.2編譯時(shí)引用動(dòng)態(tài)鏈接庫的幾種方式(1)當(dāng)所用的動(dòng)態(tài)鏈接庫在系統(tǒng)目錄(/lib,/usr/lib)下時(shí),可用編譯選項(xiàng)-l來引用.即:#cc-lmy-oadyady.c#注:編譯時(shí)用-l選項(xiàng)引用動(dòng)態(tài)鏈接庫時(shí),庫名須使用其縮寫形式.本例的my,表示引用libmy.so庫.若引用光標(biāo)庫libncurses.so,須用-lncurses.注意,-l選項(xiàng)與參數(shù)之間不能有空格,否則會(huì)出錯(cuò).(2)當(dāng)所用的動(dòng)態(tài)鏈接庫在系統(tǒng)目錄(/lib,/usr/lib)以外的目錄時(shí),須用編譯選項(xiàng)-L來指定動(dòng)態(tài)鏈接庫所在的目錄(供編譯器查找用),同時(shí)用-l選項(xiàng)指定縮寫的動(dòng)態(tài)鏈接庫名.即:#cc-L/usr/zz

39、z/lib-lmy-oadyady.c#(3)直接引用所需的動(dòng)態(tài)鏈接庫.即:#cc-oadyady.clibmy.so#或#cc-oadyady.c/lib/libmy.so#等等.其中,動(dòng)態(tài)鏈接庫的庫名可以采用相對路徑形式(文件名不以/開頭),也可采用絕對路徑形式(文件名以/開頭).五、動(dòng)態(tài)鏈接程序的運(yùn)行與檢查5.1運(yùn)行編譯連接好含動(dòng)態(tài)函數(shù)的程序后,就可以運(yùn)行它了.動(dòng)態(tài)鏈接程序因?yàn)楣蚕砹讼到y(tǒng)中的動(dòng)態(tài)鏈接庫,所以其空間占用很小.但這并不意味功能的減少,它的執(zhí)行與靜態(tài)連接的程序執(zhí)行,效果完全相同.在命令提示符下鍵入程序名及相關(guān)參數(shù)后回車即可,如下例:$ady動(dòng)態(tài)鏈接庫高級應(yīng)用示范當(dāng)前日期:2002-03-11當(dāng)前時(shí)間:19:39:06$5.2檢查檢查什么?檢查動(dòng)態(tài)鏈接程序究竟需要哪些共享庫,系統(tǒng)中是否已有這些庫,沒有的話,用戶好想辦法把這些庫裝上.怎么檢查呢?這里,告訴你一個(gè)實(shí)用程序-ldd,這個(gè)程序就是專門用來檢查動(dòng)態(tài)鏈接程序依賴哪些共享庫的.ldd命令行用法如下:ldd-version-v|-verbose-d|-data-relocs-r|-function-relocs-helpFILE.各選項(xiàng)說明如下:(1)-version:此選項(xiàng)用于打印出ldd的版本號.(2)-v或-verbose:此選項(xiàng)指示ldd輸出關(guān)于所依賴的動(dòng)態(tài)鏈

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論