LINUX動態(tài)鏈接庫的創(chuàng)建與使用_第1頁
LINUX動態(tài)鏈接庫的創(chuàng)建與使用_第2頁
LINUX動態(tài)鏈接庫的創(chuàng)建與使用_第3頁
LINUX動態(tài)鏈接庫的創(chuàng)建與使用_第4頁
LINUX動態(tài)鏈接庫的創(chuàng)建與使用_第5頁
已閱讀5頁,還剩12頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、一,LINUX系統(tǒng)中動態(tài)鏈接庫的創(chuàng)建與使用大家都知道,在WINDOWS系統(tǒng)中有很多的動態(tài)鏈接庫(以.DLL為后綴的文件,DLL即 Dynamic Link Library)。這種動態(tài)鏈接庫,和靜態(tài)函數(shù)庫不同,它里面的函數(shù)并不是執(zhí)行程序本身的一部分,而是根據(jù)執(zhí)行程序需要按需裝入,同時其執(zhí)行代碼可在多個 執(zhí)行程序間共享,節(jié)省了空間,提高了效率,具備很高的靈活性,得到越來越多程序員和用戶的青睞。那么,在LINUX系統(tǒng)中有無這樣的函數(shù)庫呢?答案是肯定的,LINUX的動態(tài)鏈接庫不僅有,而且為數(shù)不少。在/lib目錄下,就有許多 以.so作后綴的文件,這就是LINUX系統(tǒng)應用的動態(tài)鏈接庫,只不過與WINDO

2、WS叫法不同,它叫so,即Shared Object,共享對象。(在LINUX下,靜態(tài)函數(shù)庫是以.a作后綴的) X-WINDOW作為LINUX下的標準圖形窗口界面,它本身就采用了很多的動態(tài)鏈接庫(在/usr/X11R6/lib目錄下),以方便程序間的共享, 節(jié)省占用空間。著名的APACHE網頁服務器,也采用了動態(tài)鏈接庫,以便擴充程序功能。你只需將PHP動態(tài)鏈接庫拷到其共享目錄,修改一下配 置,APACHE就可以支持PHP網頁了。如果你愿意,可以自己編寫動態(tài)鏈接庫,讓APACHE支持你自己定義的網頁格式。這就是動態(tài)鏈接的好處。1、LINUX下動態(tài)鏈接庫的創(chuàng)建在LINUX系統(tǒng)下,創(chuàng)建動態(tài)鏈接庫是件

3、再簡單不過的事情。只要在編譯函數(shù)庫源程序時加上-shared選項即可,這樣所生成的執(zhí)行程序即為動態(tài)鏈接庫。從某種意義上來說,動態(tài)鏈接庫也是一種執(zhí)行程序。按一般規(guī)則,程序名應帶.so后綴。下面舉個例子說說。我準備編寫兩個函數(shù),一個用于查詢當前日期getdate,一個用于查詢當前時間gettime,并將這兩個函數(shù)存于動態(tài)鏈接庫my.so中。為此,需要做以下幾項工作。1.1 編寫用戶接口文件datetime.h,內容如下(每行前面的數(shù)字為行號):- 1 /* datetime.h : 縱橫軟件制作中心雨亦奇編寫, 2001-06-28. */2 3 #ifndef _DATETIME_H4 5 #d

4、efine _DATETIME_H6 7 /* 日期結構 */8 typedef struct9 10 int year;11 int mon;12 int day;13 DATETYPE;14 15 /* 時間結構 */16 typedef struct17 18 char hour;19 char min;20 char sec;21 TIMETYPE;22 23 /* 函數(shù)原型說明 */24 25 #ifdef SHARED26 int (*getdate)(DATETYPE *d);27 #else28 int getdate(DATETYPE *d);29 #endif30 31 #

5、ifdef SHARED32 int (*gettime)(TIMETYPE *t);33 #else34 int gettime(TIMETYPE *t);35 #endif36 37 #endif38 - 這個用戶接口文件中,先定義了日期與時間結構,接著定義一下函數(shù)的原型。動態(tài)函數(shù)與靜態(tài)函數(shù)的原型說明不同的是,動態(tài)函數(shù)應使用(*函數(shù)名)的形式,以便引用其指針。若要引用文件中的動態(tài)函數(shù)說明,用戶應該定義一下SHARED宏,這樣才能使用。1.2 編寫getdate.c,源程序如下:- 1 /* getdate.c : 縱橫軟件制作中心雨亦奇編寫, 2001-06-28. */2 3 #incl

6、ude "time.h"4 #include "datetime.h"5 6 int getdate(DATETYPE *d)7 8 long ti;9 struct tm *tm;10 11 time(&ti);12 tm=localtime(&ti);13 d->year=tm->tm_year+1900;14 d->mon=tm->tm_mon+1;15 d->day=tm->tm_mday;16 17 - 在getdate函數(shù)中,先調用time取得以秒計的系統(tǒng)時間,再用localtime函數(shù)轉換

7、一下時間結構,最后調整得到正確的日期。1.3 編寫gettime.c,源程序如下:- 1 /* gettime.c : 縱橫軟件制作中心雨亦奇編寫, 2001-06-28. */2 3 #include "time.h"4 #include "datetime.h"5 6 int gettime(TIMETYPE *t)7 8 long ti;9 struct tm *tm;1011 time(&ti);12 tm=localtime(&ti);13 t->hour=tm->tm_hour;14 t->min=tm-&g

8、t;tm_min;15 t->sec=tm->tm_sec;16 17 - gettime函數(shù)與getdate函數(shù)相仿,先用time函數(shù)取得以秒計的系統(tǒng)時間,再用localtime函數(shù)轉換一下時間結構,最后返回當前的時間(不需調整)。1.4 編寫維護文件makefile-lib,內容如下:- 1 # makefile-lib : 縱橫軟件制作中心雨亦奇編寫, 2001-06-28.2 3 all : my.so4 5 SRC = getdate.c gettime.c6 7 TGT = $(SRC:.c=.o)8 9 $(SRC) : datetime.h10 touch $11

9、12 %.o : %.c13 cc -c $?14 15 # 動態(tài)函數(shù)庫(my.so)生成16 my.so : $(TGT)17 cc -shared -o $ $(TGT)18 - 編寫維護文件的目的,在于方便程序員維護程序,尤其是維護比較大的工程項目。一個素質良好的程 序員應該學會熟練地編寫維護文件makefile。定義了文件間的依賴關系后,一旦源文件發(fā)生變化,僅需make一下,其目標文件維護代碼會自動執(zhí)行,從 而自動更新目標文件,減少了許多工作量。注意: 每行維護代碼必須以TAB(跳格鍵)開始,不是的話make時將出錯。本維護文件第1行是注釋行,以#號開頭;文件第3行定義所有需要維護的函

10、數(shù)庫;第5行定義相關 源程序文件;第7行定義目標文件;第9-10行說明所有源程序依賴于datetime.h頭文件,并有相應維護代碼,即touch一下,更新一下源文件的 時間;第12-13行定義.o文件依賴于相應的.c文件,并指定了維護代碼,即用cc編譯一下;第16-17行定義共享庫my.so依賴的目標文件,維護 代碼中用-shared編譯選項,以生成動態(tài)鏈接庫my.so。1.5 運行make -f makefile-lib 命令make運行后,動態(tài)鏈接庫my.so就產生了,我們就可以在程序中調用了。如果想讓系統(tǒng)所有 用戶都可以使用,則應以root用戶登錄系統(tǒng),將這個庫拷貝到/lib目錄下(命令

11、:cp my.so /lib),或者在/lib目錄下建個符號連接即可(命令:ln -s pwd/my.so /lib)。2、LINUX下動態(tài)鏈接庫的使用2.1 重要的dlfcn.h頭文件LINUX下使用動態(tài)鏈接庫,源程序需要包含dlfcn.h頭文件,此文件定義了調用動態(tài)鏈接庫的函數(shù)的原型。下面詳細說明一下這些函數(shù)。 dlerror原型為: const char *dlerror(void);當動態(tài)鏈接庫操作函數(shù)執(zhí)行失敗時,dlerror可以返回出錯信息,返回值為NULL時表示操作函數(shù)執(zhí)行成功。 dlopen原型為: void *dlopen (const char *filename, int

12、 flag);dlopen用于打開指定名字(filename)的動態(tài)鏈接庫,并返回操作句柄。filename: 如果名字不以/開頭,則非絕對路徑名,將按下列先后順序查找該文件。(1) 用戶環(huán)境變量中的LD_LIBRARY值;(3) 目錄/lib,/usr/libflag表示在什么時候解決未定義的符號(調用)。取值有兩個:1) RTLD_LAZY : 表明在動態(tài)鏈接庫的函數(shù)代碼執(zhí)行時解決。2) RTLD_NOW : 表明在dlopen返回前就解決所有未定義的符號,一旦未解決,dlopen將返回錯誤。dlopen調用失敗時,將返回NULL值,否則返回的是操作句柄。 dlsym : 取函數(shù)執(zhí)行地址原

13、型為: void *dlsym(void *handle, char *symbol);dlsym根據(jù)動態(tài)鏈接庫操作句柄(handle)與符號(symbol),返回符號對應的函數(shù)的執(zhí)行代碼地址。由此地址,可以帶參數(shù)執(zhí)行相應的函數(shù)。如程序代碼: void (*add)(int x,int y); /* 說明一下要調用的動態(tài)函數(shù)add */add=dlsym("xxx.so","add"); /* 打開xxx.so共享庫,取add函數(shù)地址 */add(89,369); /* 帶兩個參數(shù)89和369調用add函數(shù) */ dlclose : 關閉動態(tài)鏈接庫原型為

14、: int dlclose (void *handle);dlclose用于關閉指定句柄的動態(tài)鏈接庫,只有當此動態(tài)鏈接庫的使用計數(shù)為0時,才會真正被系統(tǒng)卸載。2.2 在程序中使用動態(tài)鏈接庫函數(shù) 程序范例下面的程序裝載了動態(tài)鏈接庫my.so,并用getdate,gettime取得當前日期與時間后輸出。- 1 /*/2 /* 文件名稱: dy.c */3 /* 功能描述: 動態(tài)鏈接庫應用示范程序 */4 /* 程序編寫: 縱橫軟件制作中心雨亦奇 */5 /* 編寫時間: 2001-06-28 */6 /*/7 8 #include "stdio.h" /* 包含標準輸入輸出文件

15、 */9 10 #include "dlfcn.h" /* 包含動態(tài)鏈接功能接口文件 */11 #define SOFILE "./my.so" /* 指定動態(tài)鏈接庫名稱 */12 13 #define SHARED /* 定義宏,確認共享,以便引用動態(tài)函數(shù) */14 #include "datetime.h" /* 包含用戶接口文件 */15 16 main()17 18 DATETYPE d;19 TIMETYPE t;20 void *dp;21 char *error;22 23 puts("動態(tài)鏈接庫應用示范&qu

16、ot;);24 25 dp=dlopen(SOFILE,RTLD_LAZY); /* 打開動態(tài)鏈接庫 */26 27 if (dp=NULL) /* 若打開失敗則退出 */28 29 fputs(dlerror(),stderr);30 exit(1);31 32 33 getdate=dlsym(dp,"getdate"); /* 定位取日期函數(shù) */34 35 error=dlerror(); /* 檢測錯誤 */36 if (error) /* 若出錯則退出 */37 38 fputs(error,stderr);39 exit(1);40 41 42 getdate

17、(&d); /* 調用此共享函數(shù) */43 printf("當前日期: %04d-%02d-%02dn",d.year,d.mon,d.day);44 45 gettime=dlsym(dp,"gettime"); /* 定位取時間函數(shù) */46 47 error=dlerror(); /* 檢測錯誤 */48 if (error) /* 若出錯則退出 */49 50 fputs(error,stderr);51 exit(1);52 53 54 gettime(&t); /* 調用此共享函數(shù) */55 printf("當前時間

18、: %02d:%02d:%02dn",t.hour,t.min,t.sec);56 57 dlclose(dp); /* 關閉共享庫 */58 59 exit(0); /* 成功返回 */60 61 - 程序說明:第8行: 包含標準輸入輸出頭文件,因為程序中使用了printf,puts,fputs等標準輸入輸出函數(shù),需要讓編譯器根據(jù)頭文件中函數(shù)的原型,檢查一下語法;第10-11行: 包含動態(tài)鏈接庫功能頭文件,并定義動態(tài)鏈接庫名稱;第13-14行: 定義宏SHARED以便引用14行的頭文件datetime.h中的動態(tài)函數(shù)說明;第25行: 用dlopen打開SOFILE共享庫,返回句柄d

19、p;第27-31行: 檢測dp是否為空,為空則顯示錯誤后退出;第33行: 用dlsym取得getdate函數(shù)動態(tài)地址;第35-40行: 如果dlerror返回值不為空,則dlsym執(zhí)行出錯,程序顯示錯誤后退出;第42-43行: 執(zhí)行getdate調用,輸出當前日期;第45行: 用dlsym取得gettime函數(shù)動態(tài)地址;第47-52行: 如果dlerror返回值不為空,則dlsym執(zhí)行出錯,程序顯示錯誤后退出;第54-55行: 執(zhí)行gettime調用,輸出當前時間;第57行: 用dlclose關閉dp所指示的動態(tài)鏈接庫;第59行: 程序退出,返回0值。 編寫維護文件維護文件makefile內容

20、如下:-1 # makefile : 縱橫軟件制作中心雨亦奇編寫, 2001-06-28.2 3 all : dy4 5 DYSRC = dy.c6 7 DYTGT = $(DYSRC:.c=.o)8 9 %.o : %.c10 cc -c $?11 12 # 動態(tài)庫應用示范程序13 dy : $(DYTGT)14 cc -rdynamic -s -o $ $(DYTGT) -ldl15 -維護文件說明:第3行: 定義所有需要維護的模塊;第5行: 定義源程序;第7行: 定義目標文件;第9-10行: 定義.o文件依賴于.c文件,維護代碼為“cc -c 變動的源文件名”;第13-14行: 定義dy

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

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

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

24、義程序所需的常量,自定義類型及函數(shù)原型說明等.其中的函數(shù)原型說明,則供編譯器檢查語法,用于排除引用參數(shù)時類型不一致的錯誤.只有編寫合格的動態(tài)鏈接庫頭文件,程序員才能正確使用動態(tài)鏈接庫內的函數(shù). 動態(tài)鏈接庫頭文件要采用C語言標準格式,其中的動態(tài)函數(shù)原型定義,不必象上文介紹的那樣用(*動態(tài)函數(shù)名)的描述形式.請看下面的例子:(每行開始的數(shù)字為所在行行號,為筆者添加,供注解使用) 1 /* adatetime.h : 縱橫軟件制作中心雨亦奇(zhsoft)編寫, 2002-03-06. */ 2 3 #ifndef _DATETIME_H 4 5 #define _DATETIME_H 6 7 /*

25、 日期結構 */ 8 typedef struct 9 10 int year; 11 int mon; 12 int day; 13 DATETYPE; 14 15 /* 時間結構 */ 16 typedef struct 17 18 char hour; 19 char min; 20 char sec; 21 TIMETYPE; 22 23 int getdate(DATETYPE *d); /* 取當前日期 */ 24 int gettime(TIMETYPE *t); /* 取當前時間 */ 25 26 #endif 27 注:與上文的datetime.h文件比較,從該頭文件第23,

26、24行可以看到,動態(tài)函數(shù)getdate,gettime的原型定義改變了,不再使用(*getdate),(*gettime)的格式了(這種格式使用較為羅嗦). 二、正確編譯與命名動態(tài)鏈接庫 為了讓GCC編譯器生成動態(tài)鏈接庫,編譯時須加選項-shared.(這點須牢記) LINUX系統(tǒng)中,為了讓動態(tài)鏈接庫能被系統(tǒng)中其它程序共享,其名字應符合“l(fā)ib*.so*”這種格式.如果某個動態(tài)鏈接庫不符合此格式,則LINUX的動態(tài)鏈接庫自動裝入程序(ld.so)將搜索不到此鏈接庫,其它程序也無法共享之. 格式中,第一個*通常表示為簡寫的庫名,第二個*通常表示為該庫的版本號.如:在我的系統(tǒng)中,基本C動態(tài)鏈接庫的

27、名字為libc.so.6,線程 pthread動態(tài)鏈接庫的名字為libpthread.so.0等等.本文例子所生成的動態(tài)鏈接庫的名字為libmy.so,雖沒有版本號,但也符合所 要求的格式. 生成該動態(tài)鏈接庫的維護文件makefile-lib內容如下: 1 # makefile : 縱橫軟件制作中心雨亦奇編寫, 2002-03-07. 2 3 all : libmy.so 4 5 SRC = getdate.c gettime.c 6 7 TGT = $(SRC:.c=.o) 8 9 $(SRC) : adatetime.h 10 touch $ 11 12 %.o : %.c 13 cc -

28、c $? 14 15 # 動態(tài)鏈接庫(libmy.so)生成 16 libmy.so : $(TGT) 17 cc -s -shared -o $ $(TGT) 18 運行命令: $ make -f makefile-lib $ 即生成libmy.so庫. 注: 維護文件中,第17行用-shared選項以生成動態(tài)鏈接庫,用-s選項以去掉目標文件中的符號表,從而減小文件長度. 三、共享動態(tài)鏈接庫 3.1 動態(tài)鏈接庫配置文件 為了讓動態(tài)鏈接庫為系統(tǒng)所使用,需要維護動態(tài)鏈接庫的配置文件-/etc/ld.so.conf.此文件內,存放著可被LINUX共享的動態(tài)鏈接 庫所在目錄的名字(系統(tǒng)目錄/lib,

29、/usr/lib除外),各個目錄名間以空白字符(空格,換行等)或冒號或逗號分隔.一般的LINUX發(fā)行版中,此 文件均含一個共享目錄/usr/X11R6/lib,為X window窗口系統(tǒng)的動態(tài)鏈接庫所在的目錄. 下面看看我的系統(tǒng)中此文件的內容如何: # cat /etc/ld.so.conf /usr/X11R6/lib /usr/zzz/lib # 由上可以看出,該動態(tài)庫配置文件中,增加了一個/usr/zzz/lib目錄.這是我自己新建的共享庫目錄,下面存放我新開發(fā)的可供系統(tǒng)共享的動態(tài)鏈接庫. 3.2 動態(tài)鏈接庫管理命令 為了讓動態(tài)鏈接庫為系統(tǒng)所共享,還需運行動態(tài)鏈接庫的管理命令-ldcon

30、fig.此執(zhí)行程序存放在/sbin目錄下. ldconfig命令的用途,主要是在默認搜尋目錄(/lib和/usr/lib)以及動態(tài)庫配置文件/etc/ld.so.conf內所列的目錄 下,搜索出可共享的動態(tài)鏈接庫(格式如前介紹,lib*.so*),進而創(chuàng)建出動態(tài)裝入程序(ld.so)所需的連接和緩存文件.緩存文件默認為/etc /ld.so.cache,此文件保存已排好序的動態(tài)鏈接庫名字列表. ldconfig通常在系統(tǒng)啟動時運行,而當用戶安裝了一個新的動態(tài)鏈接庫時,就需要手工運行這個命令. ldconfig命令行用法如下: ldconfig -v|-verbose -n -N -X -f C

31、ONF -C CACHE -r ROOT -l -p|-print-cache -c FORMAT -format=FORMAT -V -?|-help|-usage path. ldconfig可用的選項說明如下: (1) -v或-verbose : 用此選項時,ldconfig將顯示正在掃描的目錄及搜索到的動態(tài)鏈接庫,還有它所創(chuàng)建的連接的名字. (2) -n : 用此選項時,ldconfig僅掃描命令行指定的目錄,不掃描默認目錄(/lib,/usr/lib),也不掃描配置文件/etc/ld.so.conf所列的目錄. (3) -N : 此選項指示ldconfig不重建緩存文件(/etc/l

32、d.so.cache).若未用-X選項,ldconfig照常更新文件的連接. (4) -X : 此選項指示ldconfig不更新文件的連接.若未用-N選項,則緩存文件正常更新. (5) -f CONF : 此選項指定動態(tài)鏈接庫的配置文件為CONF,系統(tǒng)默認為/etc/ld.so.conf. (6) -C CACHE : 此選項指定生成的緩存文件為CACHE,系統(tǒng)默認的是/etc/ld.so.cache,此文件存放已排好序的可共享的動態(tài)鏈接庫的列表. (7) -r ROOT : 此選項改變應用程序的根目錄為ROOT(是調用chroot函數(shù)實現(xiàn)的).選擇此項時,系統(tǒng)默認的配置文件/etc/ld.s

33、o.conf,實際對應的為 ROOT/etc/ld.so.conf.如用-r /usr/zzz時,打開配置文件/etc/ld.so.conf時,實際打開的是/usr/zzz/etc/ld.so.conf文件.用此選項,可以 大大增加動態(tài)鏈接庫管理的靈活性. (8) -l : 通常情況下,ldconfig搜索動態(tài)鏈接庫時將自動建立動態(tài)鏈接庫的連接.選擇此項時,將進入專家模式,需要手工設置連接.一般用戶不用此項. (9) -p或-print-cache : 此選項指示ldconfig打印出當前緩存文件所保存的所有共享庫的名字. (10) -c FORMAT 或 -format=FORMAT : 此

34、選項用于指定緩存文件所使用的格式,共有三種:old(老格式),new(新格式)和compat(兼容格式,此為默認格式). (11) -V : 此選項打印出ldconfig的版本信息,而后退出. (12) -? 或 -help 或 -usage : 這三個選項作用相同,都是讓ldconfig打印出其幫助信息,而后退出. 舉三個例子: 例1: # ldconfig -p 793 libs found in cache /etc/ld.so.cache' libzvt.so.2 (libc6) => /usr/lib/libzvt.so.2 libzvt.so (libc6) =>

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

36、略的部分. 例2: # ldconfig -v /lib: liby.so.1 -> liby.so.1 libnss_wins.so -> libnss_wins.so . /usr/lib: libjscript.so.2 -> libjscript.so. libkspell.so.2 -> libkspell.so.2.0.0 . /usr/X11R6/lib: libmej-0.8.10.so -> libmej-0.8.10.so libXaw3d.so.7 -> libXaw3d.so.7.0 . # 注: ldconfig命令在運行正常的情況

37、下,默認不輸出什么東西.本例中用了-v選項,以使ldconfig在運行時輸出正在掃描的目錄及搜索到的共享庫, 用戶可以清楚地看到運行的結果.執(zhí)行結束后,ldconfig將刷新緩存文件/etc/ld.so.cache. 例3: # ldconfig /usr/zhsoft/lib # 注: 當用戶在某個目錄下面創(chuàng)建或拷貝了一個動態(tài)鏈接庫,若想使其被系統(tǒng)共享,可以執(zhí)行一下"ldconfig 目錄名"這個命令.此命令的功能在于讓ldconfig將指定目錄下的動態(tài)鏈接庫被系統(tǒng)共享起來,意即:在緩存文件/etc/ld.so.cache中追 加進指定目錄下的共享庫.本例讓系統(tǒng)共享了/u

38、sr/zhsoft/lib目錄下的動態(tài)鏈接庫.需要說明的是,如果此目錄不在/lib,/usr/lib 及/etc/ld.so.conf文件所列的目錄里面,則再度運行l(wèi)dconfig時,此目錄下的動態(tài)鏈接庫可能不被系統(tǒng)共享了. 3.3 動態(tài)鏈接庫如何共享 了解了以上知識,我們可以采用以下三種方法來共享動態(tài)鏈接庫:(注:均須在超級用戶狀態(tài)下操作,以我的動態(tài)鏈接庫libmy.so共享過程為例) (1)拷貝動態(tài)鏈接庫到系統(tǒng)共享目錄下,或在系統(tǒng)共享目錄下為該動態(tài)鏈接庫建立個連接(硬連接或符號連接均可,常用符號連接).這里說的系統(tǒng)共享目 錄,指的是LINUX動態(tài)鏈接庫存放的目錄,它包含/lib,/usr/

39、lib以及/etc/ld.so.conf文件內所列的一系列目錄. # cp libmy.so /lib # ldconfig # 或: # ln -s pwd/libmy.so /lib # ldconfig # (2)將動態(tài)鏈接庫所在目錄名追加到動態(tài)鏈接庫配置文件/etc/ld.so.conf中. # pwd >> /etc/ld.so.conf # ldconfig # (3)利用動態(tài)鏈接庫管理命令ldconfig,強制其搜索指定目錄,并更新緩存文件,便于動態(tài)裝入. # ldconfig pwd # 需要說明的是,這種操作方法雖然有效,但效果是暫時的,供程序測試還可以,一旦再度

40、運行l(wèi)dconfig,則緩存文件內容可能改變,所需的動態(tài)鏈接 庫可能不被系統(tǒng)共享了.與之相比較,前兩種方法是可靠的方法,值得業(yè)已定型的動態(tài)鏈接庫共享時采用.前兩種方法還有一個特點,即最后一條命令都是 ldconfig,也即均需要更新一下緩存文件,以確保動態(tài)鏈接庫的共享生效. 四、含有動態(tài)函數(shù)的程序的編譯 4.1 防止編譯因未指定動態(tài)鏈接庫而出錯 當一個程序使用動態(tài)函數(shù)時,編譯該程序時就必須指定含所用動態(tài)函數(shù)的動態(tài)鏈接庫,否則編譯將會出錯退出.如本文示例程序ady.c的編譯(未明確引用動態(tài)鏈接庫libmy.so): # cc -o ady ady.c /tmp/ccL4FsJp.o: In fu

41、nction main': /tmp/ccL4FsJp.o(.text+0x43): undefined reference to gettime' collect2: ld returned 1 exit status # 注: 因為ady.c所含的動態(tài)函數(shù)getdate,gettime不在系統(tǒng)函數(shù)庫中,所以連接時出錯. 4.2 編譯時引用動態(tài)鏈接庫的幾種方式 (1)當所用的動態(tài)鏈接庫在系統(tǒng)目錄(/lib,/usr/lib)下時,可用編譯選項-l來引用.即: # cc -lmy -o ady ady.c # 注:編譯時用-l選項引用動態(tài)鏈接庫時,庫名須使用其縮寫形式.本例的m

42、y,表示引用libmy.so庫.若引用光標庫libncurses.so,須用-lncurses.注意,-l選項與參數(shù)之間不能有空格,否則會出錯. (2)當所用的動態(tài)鏈接庫在系統(tǒng)目錄(/lib,/usr/lib)以外的目錄時,須用編譯選項-L來指定動態(tài)鏈接庫所在的目錄(供編譯器查找用),同時用-l選項指定縮寫的動態(tài)鏈接庫名.即: # cc -L/usr/zzz/lib -lmy -o ady ady.c # (3)直接引用所需的動態(tài)鏈接庫.即: # cc -o ady ady.c libmy.so # 或 # cc -o ady ady.c /lib/libmy.so # 等等.其中,動態(tài)鏈接庫

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

溫馨提示

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

評論

0/150

提交評論