LINUX動(dòng)態(tài)鏈接庫高級(jí)應(yīng)用復(fù)習(xí)課程_第1頁
LINUX動(dòng)態(tài)鏈接庫高級(jí)應(yīng)用復(fù)習(xí)課程_第2頁
LINUX動(dòng)態(tài)鏈接庫高級(jí)應(yīng)用復(fù)習(xí)課程_第3頁
LINUX動(dòng)態(tài)鏈接庫高級(jí)應(yīng)用復(fù)習(xí)課程_第4頁
LINUX動(dòng)態(tài)鏈接庫高級(jí)應(yīng)用復(fù)習(xí)課程_第5頁
已閱讀5頁,還剩28頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、Good is good, but better carries it.精益求精,善益求善。LINUX動(dòng)態(tài)鏈接庫高級(jí)應(yīng)用-在HYPERLINK/u2/74682/showart.php?id=1154509t_blankLINUX下動(dòng)態(tài)鏈接庫的創(chuàng)建與應(yīng)用一文中,我介紹了LINUX動(dòng)態(tài)鏈接庫的基本知識(shí).其要點(diǎn)是:用戶根據(jù)實(shí)際情況需要,利用dlopen,dlsym,dlclose等動(dòng)態(tài)鏈接庫操作函數(shù),裝入指定的動(dòng)態(tài)鏈接庫中指定的函數(shù),然后加以執(zhí)行.程序中使用很少的動(dòng)態(tài)函數(shù)時(shí),這樣的做法尚可.如果程序需要調(diào)用大量的動(dòng)態(tài)函數(shù),那么采用這樣的編程手段將是非常繁復(fù)的,所以我們必須使用一種更為聰明的辦法,以

2、減少代碼量,提高工作效率.這就是現(xiàn)在我要舉例介紹的LINUX動(dòng)態(tài)鏈接庫高級(jí)應(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è)程序引用,里面一般定義程序所需的常量,自定義類型及函數(shù)原型說明等.其中的函數(shù)原型說明,則供編譯器檢查語法,用于排除引用參數(shù)時(shí)類型不一致的錯(cuò)誤.只有編寫合格的動(dòng)

3、態(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ù)名)的描述形式.請(qǐng)看下面的例子:(每行開始的數(shù)字為所在行行號(hào),為筆者添加,供注解使用)1/*adatetime.h:縱橫軟件制作中心雨亦奇()編寫,2002-03-06.*/23#ifndef_DATETIME_H45#define_DATETIME_H67/*日期結(jié)構(gòu)*/8typedefstruct910intyear;11intmon;12intday;13DATETYPE;1415/*時(shí)間結(jié)構(gòu)*/16typedefstruct1718cha

4、rhour;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)的格式了(這種格式使用較為羅嗦).二、正確編譯與命名動(dòng)態(tài)鏈接庫為了讓GCC編譯器生成動(dòng)態(tài)鏈接庫,編譯時(shí)須加選項(xiàng)-shared.(這點(diǎn)須牢記)LINUX系統(tǒng)中,為了讓動(dòng)態(tài)鏈接庫能被系

5、統(tǒng)中其它程序共享,其名字應(yīng)符合“l(fā)ib*.so*”這種格式.如果某個(gè)動(dòng)態(tài)鏈接庫不符合此格式,則LINUX的動(dòng)態(tài)鏈接庫自動(dòng)裝入程序(ld.so)將搜索不到此鏈接庫,其它程序也無法共享之.格式中,第一個(gè)*通常表示為簡(jiǎn)寫的庫名,第二個(gè)*通常表示為該庫的版本號(hào).如:在我的系統(tǒng)中,基本C動(dòng)態(tài)鏈接庫的名字為libc.so.6,線程pthread動(dòng)態(tài)鏈接庫的名字為libpthread.so.0等等.本文例子所生成的動(dòng)態(tài)鏈接庫的名字為libmy.so,雖沒有版本號(hào),但也符合所要求的格式.生成該動(dòng)態(tài)鏈接庫的維護(hù)文件makefile-lib內(nèi)容如下:1#makefile:縱橫軟件制作中心雨亦奇編寫,2002-03

6、-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)鏈接庫,用-s選項(xiàng)以去掉目標(biāo)文件中的符號(hào)表,從而減小文件長(zhǎng)度.三、共享動(dòng)態(tài)鏈接庫3.1動(dòng)態(tài)鏈接庫配置文件為了讓動(dòng)態(tài)鏈接庫為系統(tǒng)所使用

7、,需要維護(hù)動(dòng)態(tài)鏈接庫的配置文件-/etc/ld.so.conf.此文件內(nèi),存放著可被LINUX共享的動(dòng)態(tài)鏈接庫所在目錄的名字(系統(tǒng)目錄/lib,/usr/lib除外),各個(gè)目錄名間以空白字符(空格,換行等)或冒號(hào)或逗號(hào)分隔.一般的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/lib#由上可以看出,該動(dòng)態(tài)庫配置文件中,增加了一個(gè)/usr/zzz/lib目錄.這是我自己新建的共享庫目錄,下面存放我新開發(fā)的可

8、供系統(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,此文件保存已排好序的動(dòng)態(tài)鏈接庫名字列表.ldconfig通常在系統(tǒng)啟動(dòng)時(shí)運(yùn)行,而當(dāng)用戶安裝了一個(gè)新的動(dòng)態(tài)鏈接庫時(shí),就需要手工運(yùn)行這個(gè)

9、命令.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僅掃描命令行指定的目錄,不掃描默認(rèn)目錄(/lib,/usr/lib),也不掃描配置文件/etc/ld.so.conf所列的目錄.(3)-N:此選項(xiàng)指示

10、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)鏈接庫的列表.(7)-rROOT:此選項(xiàng)改變應(yīng)用程序的根目錄為ROOT(是調(diào)用chroot函數(shù)實(shí)現(xiàn)的).選擇此項(xiàng)時(shí),系統(tǒng)默認(rèn)的配置文件/etc/l

11、d.so.conf,實(shí)際對(duì)應(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打印出當(dāng)前緩存文件所保存的所有共享庫的名字.(10)-cFORMAT或-format=FORMAT:此選項(xiàng)用于指定緩存文件所使用的格

12、式,共有三種: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.so(libc6)=/usr/lib/libzvt.solibz.so.1.1.3(libc6)=/usr/lib/libz.so.1

13、.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行開始便是一系列共享庫的名字及其全名(絕對(duì)路徑).因?yàn)閷?shí)際輸出結(jié)果太多,為節(jié)省篇幅,以.表示省略的部分.例2:#ldconfig-v/lib:liby.so.1-liby.so.1libnss_wins.so-libnss_wins.so./us

14、r/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í)輸出正在掃描的目錄及搜索到的共享庫,用戶可以清楚地看到運(yùn)行的結(jié)果.執(zhí)行結(jié)束后,ldconfig將刷新緩存文件/etc/ld.so.cache.例3:#ldconfig/usr/zh

15、soft/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)dconfig時(shí),此目錄下的動(dòng)態(tài)鏈接庫可能不被系統(tǒng)共享了.3.3動(dòng)態(tài)鏈接庫如何共享了解了以上知識(shí),我們可以采用以下三種方法來共享動(dòng)態(tài)

16、鏈接庫:(注:均須在超級(jí)用戶狀態(tài)下操作,以我的動(dòng)態(tài)鏈接庫libmy.so共享過程為例)(1)拷貝動(dòng)態(tài)鏈接庫到系統(tǒng)共享目錄下,或在系統(tǒng)共享目錄下為該動(dòng)態(tài)鏈接庫建立個(gè)連接(硬連接或符號(hào)連接均可,常用符號(hào)連接).這里說的系統(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#ldconfig#(2)將動(dòng)態(tài)鏈接庫所在目錄名追加到動(dòng)態(tài)鏈接庫配置文件/etc/ld.so.conf中.#pwd/etc/ld.so.conf#l

17、dconfig#(3)利用動(dòng)態(tài)鏈接庫管理命令ldconfig,強(qiáng)制其搜索指定目錄,并更新緩存文件,便于動(dòng)態(tài)裝入.#ldconfigpwd#需要說明的是,這種操作方法雖然有效,但效果是暫時(shí)的,供程序測(cè)試還可以,一旦再度運(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)鏈接庫的共享生效.四、含有動(dòng)態(tài)函數(shù)的程序的編譯4.1防止編譯因未指定動(dòng)態(tài)鏈接庫而出錯(cuò)當(dāng)一個(gè)程序使用動(dòng)態(tài)函數(shù)時(shí),編譯該程序時(shí)就必須指定

18、含所用動(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ù)庫中,所以連接時(shí)出錯(cuò).4.2編譯時(shí)引用動(dòng)態(tài)鏈接庫的幾種方式(1)當(dāng)所用的動(dòng)態(tài)鏈接庫在系統(tǒng)目錄(/lib,/usr/lib)下時(shí),可用編譯選項(xiàng)-

19、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/zzz/lib-lmy-oadyady.c#(3)直接引用所需的動(dòng)態(tài)鏈接庫.即:#cc-oadyady.clibmy.so#或#cc-o

20、adyady.c/lib/libmy.so#等等.其中,動(dòng)態(tài)鏈接庫的庫名可以采用相對(duì)路徑形式(文件名不以/開頭),也可采用絕對(duì)路徑形式(文件名以/開頭).五、動(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)鏈接庫高級(jí)應(yīng)用示范當(dāng)前日期:2002-03-11當(dāng)前時(shí)間:19:39:06$5.2檢查檢查什么?檢查動(dòng)態(tài)鏈接程序究竟需要哪些共享庫,系統(tǒng)中是否已有這些庫,沒有的話,用

21、戶好想辦法把這些庫裝上.怎么檢查呢?這里,告訴你一個(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的版本號(hào).(2)-v或-verbose:此選項(xiàng)指示ldd輸出關(guān)于所依賴的動(dòng)態(tài)鏈接庫的盡可能詳細(xì)的信息.(3)-d或-data-relocs:此選項(xiàng)執(zhí)行重定位,并且顯示不存在的函數(shù).(4)-r或-function-relocs:此選項(xiàng)執(zhí)行數(shù)據(jù)對(duì)象與函數(shù)的重定位,

22、同時(shí)報(bào)告不存在的對(duì)象.(5)-help:此選項(xiàng)用于打印出ldd的幫助信息.注:上述選項(xiàng)中,常用-v(或-verbose)選項(xiàng).ldd的命令行參數(shù)為FILE.,即一個(gè)或多個(gè)文件名(動(dòng)態(tài)鏈接程序或動(dòng)態(tài)鏈接庫).例1:$lddadylibmy.so=./libmy.so(0 x40026000)libc.so.6=/lib/libc.so.6(0 x40028000)/lib/ld-linux.so.2=/lib/ld-linux.so.2(0 x40000000)$注:每行=前面的,為動(dòng)態(tài)鏈接程序所需的動(dòng)態(tài)鏈接庫的名字,而=后面的,則是運(yùn)行時(shí)系統(tǒng)實(shí)際調(diào)用的動(dòng)態(tài)鏈接庫的名字,所需的動(dòng)態(tài)鏈接庫在系統(tǒng)中不存在時(shí),=后面將顯示notfound,括號(hào)所括的數(shù)字為虛擬的執(zhí)行地址.本例列出ady所需的三個(gè)動(dòng)態(tài)鏈接庫,其中l(wèi)ibmy.so為自己新建的動(dòng)態(tài)鏈接庫,而libc.so.6與/lib/ld-linux.so.2均為系統(tǒng)的動(dòng)態(tài)鏈接庫,前一個(gè)為基本C庫,后一個(gè)動(dòng)態(tài)裝入庫(用于動(dòng)態(tài)鏈接庫的裝入及運(yùn)行).例2:$ldd-vadylibmy.so=./libmy.so(0 x40026000)libc.so.6=/lib/libc.so.6(0 x4002800

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(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ǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論