IT貓撲網(wǎng):您身邊最放心的安全下載站! 最新更新|軟件分類|軟件專題|手機(jī)版|論壇轉(zhuǎn)貼|軟件發(fā)布

您當(dāng)前所在位置:首頁操作系統(tǒng)LINUX → linux庫文件的制作

linux庫文件的制作

時(shí)間:2015/6/28來源:IT貓撲網(wǎng)作者:網(wǎng)管聯(lián)盟我要評論(0)

  一、為什么要使用庫文件

  我們在實(shí)際編程工作中肯定會(huì)遇到這種情況:有幾個(gè)項(xiàng)目里有一些函數(shù)模塊的功能相同,

  實(shí)現(xiàn)代碼也相同,也是我們所說的重復(fù)代碼。比如,很多項(xiàng)目里都有一個(gè)用戶驗(yàn)證的功能。

  代碼段如下:

  //UserLogin.h文件,提供函數(shù)聲明

  int IsValidUser(char* username, int namelen);

  //UserLogin.c文件,實(shí)現(xiàn)對用戶信息的驗(yàn)證

  int IsValidUser(char* username, int namelen)

  {

  int IsValid = 0;

  /*下面是具體的處理代碼,略去*/

  return IsValid

  }

  如果每個(gè)項(xiàng)目都保存著這兩個(gè)UserLogin.h和UserLogin.c文件,會(huì)有以下幾個(gè)

  弊端:

  1、每個(gè)項(xiàng)目里都有重復(fù)的模塊,造成代碼重復(fù)。

  2、代碼的重用性不好,一旦IsValidUser的代碼發(fā)生了變化,為了保持設(shè)計(jì)的一致性,

  我們還要手工修改其他項(xiàng)目里的UserLogin.c文件,既費(fèi)時(shí)又費(fèi)力,還容易出錯(cuò)。

  庫文件就是對公共代碼的一種組織形式。

  為了解決上面兩個(gè)弊端,就提出了用庫文件存放公共代碼的解決方案,其要點(diǎn)就是

  把公共的(也就是可以被多次復(fù)用的)目標(biāo)代碼從項(xiàng)目中分離出來,統(tǒng)一存放到庫文件中,

  項(xiàng)目要用到這些代碼的時(shí)候,在編譯或者運(yùn)行的時(shí)候從庫文件中取得目標(biāo)代碼即可。庫文件

  又分兩種:靜態(tài)庫和動(dòng)態(tài)庫。

  二、靜態(tài)庫與動(dòng)態(tài)庫

  如果程序是在編譯時(shí)加載庫文件的,就是使用了靜態(tài)庫。如果是在運(yùn)行時(shí)加載目標(biāo)代碼,

  就成為動(dòng)態(tài)庫。換句話說,如果是使用靜態(tài)庫,則靜態(tài)庫代碼在編譯時(shí)就拷貝到了程序的代碼段,

  程序的體積會(huì)膨脹。如果使用動(dòng)態(tài)庫,則程序中只保留庫文件的名字和函數(shù)名,在運(yùn)行時(shí)去查找

  庫文件和函數(shù)體,程序的體積基本變化不大。

  靜態(tài)庫的原則是"以空間換時(shí)間",增加程序體積,減少運(yùn)行時(shí)間;

  動(dòng)態(tài)庫則是"以時(shí)間換空間",增加了運(yùn)行時(shí)間,但減少了程序本身的體積。

  下面我們就以實(shí)際例子來看看如何使用這兩種庫.

  三、靜態(tài)庫的編寫和使用

  1、概述

  靜態(tài)庫文件的擴(kuò)展名一般為.a,其編寫步驟很簡單。

 、啪帉懞瘮(shù)代碼

 、凭幾g生成各目標(biāo)文件

 、怯胊r文件對目標(biāo)文件歸檔,生成靜態(tài)庫文件。

  注意歸檔文件名必須以lib打頭。

  使用要點(diǎn):

 、旁趃cc 的-I參數(shù)后加上靜態(tài)庫頭文件的路徑。

 、圃趃cc 的-L參數(shù)后加上庫文件所在目錄

 、窃趃cc 的-l參數(shù)后加上庫文件名,但是要去掉lib和.a擴(kuò)展名。

  比如庫文件名是libtest.a 那么參數(shù)就是 -l test

  2、編寫最簡單的靜態(tài)庫文件

  編寫如下兩個(gè)文件,注意放在同一目錄中

  myalib.h   //靜態(tài)庫頭文件

  myalib.c   //靜態(tài)庫實(shí)現(xiàn)文件

  //myalib.h 文件的內(nèi)容

  void test();

  //myalib.c 文件的內(nèi)容

  #inlcude

  void test()

  {

  printf("test\n");

  }

  3、制作庫文件

 、派赡繕(biāo)文件

  gcc -c myalib.c

  執(zhí)行完后會(huì)生成一個(gè)myalib.o文件

 、朴胊r命令歸檔,格式為ar -rc <生成的檔案文件名> <.o文件名列表>

  再次提醒,歸檔文件名一定要以lib打頭, .a結(jié)尾。

  ar -rc libtest.a myalib.o

  執(zhí)行完后會(huì)生成一個(gè)libtest.a文件

  4、使用庫文件

 、啪帉懸粋(gè)測試程序main.c,內(nèi)容為

  //main.c 測試靜態(tài)庫調(diào)用的程序

  #include "myalib.h"   //要把函數(shù)的頭文件包含進(jìn)來,否則編譯時(shí)會(huì)報(bào)錯(cuò)

  int main(int argc,char* argv[])

  {

  test();

  return 0;

  }

 、凭幾g目標(biāo)文件,注意要把靜態(tài)庫頭文件的路徑加到-I參數(shù)里面

  gcc -I /root/exercise -o main.o -c main.c

  現(xiàn)在生成了一個(gè)main.o文件

 、巧煽蓤(zhí)行文件,注意要把靜態(tài)庫文件的路徑加到-L參數(shù)里面,

  把庫文件名(去掉打頭的lib和結(jié)尾的.a)加到-l參數(shù)后面。如下面所示

  gcc -o main -L/root/exercise   main.o -ltest

  此時(shí)就會(huì)生成一個(gè)名為main的可執(zhí)行文件

  另外,注意- l參數(shù)好象應(yīng)該加到輸入文件名的后面,否則會(huì)報(bào)錯(cuò)。

  比如gcc -o main -L/root/exercise   -ltest main.o就會(huì)提示

  main.o(.text+0x11): In function `main'':

  : undefined reference to `test''

  collect2: ld returned 1 exit status

  原因我還不清楚:-)

 、葓(zhí)行可執(zhí)行文件查看效果

  執(zhí)行./main, 輸出

  test

  說明執(zhí)行成功。

  四、動(dòng)態(tài)庫的編寫

  1、概述

  動(dòng)態(tài)庫一般以.so結(jié)尾,就是shared object的意思.

  其基本生成步驟為

 、啪帉懞瘮(shù)代碼

  ⑵編譯生成動(dòng)態(tài)庫文件,要加上 -shared 和 -fpic 選項(xiàng) ,

  庫文件名以lib開頭, 以.so 結(jié)尾。

  使用方式分為兩種: 隱式調(diào)用和顯示調(diào)用

  隱式調(diào)用類似于靜態(tài)庫的使用,但需修改動(dòng)態(tài)鏈接庫的配置文件/etc/ld.so.conf;

  顯示調(diào)用則是在主程序里使用dlopen、dlsym、dlerror、dlclose等系統(tǒng)函數(shù)。

  具體的調(diào)用方式會(huì)在 "五、動(dòng)態(tài)庫的調(diào)用" 中詳細(xì)說明.

  2、編寫最簡單的動(dòng)態(tài)庫文件

  為了便于對照, 我們?nèi)匀徊捎渺o態(tài)庫中的文件做例子.

  編寫如下兩個(gè)文件,注意放在同一目錄中

  myalib.h   //靜態(tài)庫頭文件

  myalib.c   //靜態(tài)庫實(shí)現(xiàn)文件

  //myalib.h 文件的內(nèi)容

  void test();

  //myalib.c 文件的內(nèi)容

  #inlcude

  void test()

  {

  printf("test\n");

  }

  3、編譯生成動(dòng)態(tài)庫 ,庫文件名以lib開頭, 以.so 結(jié)尾。

  gcc -fpic -shared -o libtest.so myalib.c

  此時(shí)就生成一個(gè)libtest.so文件

  五、動(dòng)態(tài)庫的隱式調(diào)用

  隱式調(diào)用的含義是代碼里不出現(xiàn)庫文件名,就是說這個(gè)代碼和

  調(diào)用靜態(tài)庫的代碼是類似的。

  1、編寫測試文件

  //main.c 測試動(dòng)態(tài)庫隱式調(diào)用的程序

  #include "myalib.h"   //要把函數(shù)的頭文件包含進(jìn)來,否則編譯時(shí)會(huì)報(bào)錯(cuò)

  int main(int argc,char* argv[])

  {

  test();

  return 0;

  }

  2、 編譯測試程序,與靜態(tài)庫類似,要把頭文件的路徑加到-I參數(shù)里面

  gcc -I /root/exercise -o main.o -c main.c

  現(xiàn)在生成了一個(gè)main.o文件

  3、連接生成測試程序

  gcc -o main -L/root/exercise   main.o -ltest

  現(xiàn)在生成了一個(gè)main文件

  4、執(zhí)行測試程序

  ./main

  此時(shí)出現(xiàn)提示

  ./main: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory。

  這個(gè)原因就是程序運(yùn)行時(shí)并不知道動(dòng)態(tài)庫所在的路徑,因此自然找不到。

  解決這個(gè)問題的辦法有三種。見下節(jié)

  六、使動(dòng)態(tài)庫被系統(tǒng)共享的三種辦法

  (再次說明: 本節(jié)參考了計(jì)算機(jī)世界網(wǎng)雨亦奇的文章"LINUX動(dòng)態(tài)鏈接庫高級應(yīng)用"

  地址https://www.ccw.com.cn/htm/center/prog/02_3_13_3_2.asp)

  (1)拷貝動(dòng)態(tài)鏈接庫到系統(tǒng)共享目錄下,或在系統(tǒng)共享目錄下為該動(dòng)態(tài)鏈接庫

  建立連接(硬連接或符號連接均可,常用符號連接).這里說的系統(tǒng)共享目錄,

  指的是LINUX動(dòng)態(tài)鏈接庫存放的目錄,包括

  /lib,/usr/lib以及/etc/ld.so.conf文件內(nèi)所列的一系列目錄.

#p#副標(biāo)題#e#

  實(shí)例:執(zhí)行

  # cp libtest.so /lib

  # ldconfig

  或:

  # ln -s `pwd`/libtest.so /lib

  # ldconfig

  注意pwd前后有兩個(gè)反引號`,其目的是取得pwd命令的輸出,即當(dāng)前目錄.

  此時(shí)再執(zhí)行main,即可成功.

  (2)將動(dòng)態(tài)鏈接庫所在目錄名追加到動(dòng)態(tài)鏈接庫配置文件/etc/ld.so.conf中.

  # pwd >> /etc/ld.so.conf

  # ldconfig

  此時(shí)再執(zhí)行main,即可成功.

  (3)利用動(dòng)態(tài)鏈接庫管理命令ldconfig,強(qiáng)制其搜索指定目錄,并更新緩存文件,便于動(dòng)態(tài)裝入.

  # ldconfig `pwd`

  此時(shí)再執(zhí)行main,即可成功.

  要注意,第三種方法雖然有效,但效果是暫時(shí)的,供程序測試還可以,一旦再度運(yùn)行l(wèi)dconfig,

  則緩存文件內(nèi)容可能改變,所需的動(dòng)態(tài)鏈接庫可能不被系統(tǒng)共享了.

  而且無論哪種辦法,其實(shí)質(zhì)都是用ldconfig命令把動(dòng)態(tài)庫文件

  所在路徑加入到系統(tǒng)庫列表中,(前兩種永久,第三種臨時(shí))

  補(bǔ)充:ldconfig命令的作用(見最后說明)

關(guān)鍵詞標(biāo)簽:linux庫文件

相關(guān)閱讀

文章評論
發(fā)表評論

熱門文章 安裝紅帽子RedHat Linux9.0操作系統(tǒng)教程安裝紅帽子RedHat Linux9.0操作系統(tǒng)教程使用screen管理你的遠(yuǎn)程會(huì)話使用screen管理你的遠(yuǎn)程會(huì)話GNU/Linux安裝vmwareGNU/Linux安裝vmware如何登錄linux vps圖形界面 Linux遠(yuǎn)程桌面連如何登錄linux vps圖形界面 Linux遠(yuǎn)程桌面連

相關(guān)下載

人氣排行 Linux下獲取CPUID、硬盤序列號與MAC地址linux tc實(shí)現(xiàn)ip流量限制dmidecode命令查看內(nèi)存型號linux下解壓rar文件安裝紅帽子RedHat Linux9.0操作系統(tǒng)教程Ubuntu linux 關(guān)機(jī)、重啟、注銷 命令lcx.exe、nc.exe、sc.exe入侵中的使用方法查看linux服務(wù)器硬盤IO讀寫負(fù)載