linux共享庫(kù)

linux環(huán)境下撤缴,庫(kù)文件包含靜態(tài)函數(shù)庫(kù)和動(dòng)態(tài)函數(shù)庫(kù)兩種:

靜態(tài)函數(shù)庫(kù):

這類庫(kù)的名字一般是libxxx.a坛猪;利用靜態(tài)函數(shù)庫(kù)編譯成的文件比較大,因?yàn)?strong>整個(gè)函數(shù)庫(kù)的所有數(shù)據(jù)都會(huì)被整合進(jìn)目標(biāo)代碼中,他的優(yōu)點(diǎn)就顯而易見(jiàn)了分衫,即編譯后的執(zhí)行程序不需要外部的函數(shù)庫(kù)支持模聋,因?yàn)樗惺褂玫暮瘮?shù)都已經(jīng)被編譯進(jìn)可執(zhí)行文件了肩民。當(dāng)然這也會(huì)成為他的缺點(diǎn),因?yàn)槿绻o態(tài)函數(shù)庫(kù)改變了链方,那么你的程序必須重新編譯持痰,而且體積也較大。

動(dòng)態(tài)函數(shù)庫(kù):

這類庫(kù)的名字一般是libxxx.so祟蚀,動(dòng)態(tài)庫(kù)又稱共享庫(kù);相對(duì)于靜態(tài)函數(shù)庫(kù)工窍,動(dòng)態(tài)函數(shù)庫(kù)在編譯的時(shí)候并沒(méi)有被編譯進(jìn)目標(biāo)代碼中,你的程序執(zhí)行到相關(guān)函數(shù)時(shí)才調(diào)用該函數(shù)庫(kù)里的相應(yīng)函數(shù)前酿,因此動(dòng)態(tài)函數(shù)庫(kù)所產(chǎn)生的可執(zhí)行文件比較小患雏。由于函數(shù)庫(kù)沒(méi)有被整合進(jìn)你的程序,而是程序運(yùn)行時(shí)動(dòng)態(tài)的申請(qǐng)并調(diào)用薪者,所以程序的運(yùn)行環(huán)境中必須提供相應(yīng)的庫(kù)纵苛。動(dòng)態(tài)函數(shù)庫(kù)的改變并不影響你的程序,所以動(dòng)態(tài)函數(shù)庫(kù)的升級(jí)比較方便言津。而且如果多個(gè)應(yīng)用程序都要使用同一函數(shù)庫(kù)攻人,動(dòng)態(tài)庫(kù)就非常適合,可以減小應(yīng)用程序的體積悬槽。

在開(kāi)發(fā)過(guò)程中引入庫(kù)的作用主要包括:

1.函數(shù)模塊的功能相同,實(shí)現(xiàn)代碼也相同,通過(guò)對(duì)它們進(jìn)行封裝為庫(kù)怀吻,方便模塊之間的調(diào)用,避免代碼重復(fù)初婆。
2.封裝另外一個(gè)目的是針對(duì)接口編程蓬坡,對(duì)實(shí)現(xiàn)代碼進(jìn)行保密猿棉,利于代碼保護(hù)和代碼升級(jí)

第一節(jié):靜態(tài)函數(shù)庫(kù)

在linux中屑咳,靜態(tài)函數(shù)庫(kù)有固定的命名規(guī)則:lib+類庫(kù)名稱+.a萨赁。
把函數(shù)打包成.a靜態(tài)庫(kù)包括下面幾個(gè)步驟:

1.程序?qū)嵗?/h4>
/*************************************************************  
    FileName : myAddLib.h 
    FileFunc : 定義頭文件    
    Version  : V0.1     
    Author   : Sunrier     
    Date     : 2012-04-28 
    Descp    : Linux下實(shí)現(xiàn)靜態(tài)庫(kù)     
*************************************************************/  
#ifndef   _MYADDLIB_H_      
#define   _MYADDLIB_H_   
  
#ifdef __cplusplus  
extern "C" {  
#endif  
  
int add(int ,int );  
  
#ifdef __cplusplus  
}  
#endif  
  
#endif   
/*************************************************************      
    FileName : myAddLib.c  
    FileFunc : 定義靜態(tài)庫(kù)實(shí)現(xiàn)文件    
    Version  : V0.1      
    Author   : Sunrier      
    Date     : 2012-04-28  
    Descp    : Linux下實(shí)現(xiàn)靜態(tài)庫(kù)     
*************************************************************/    
#include <stdio.h>    
int add(int iArg1,int iArg2)    
{    
        printf("iArg1= %d , iAgr2= %d \n",iArg1,iArg2);    
        return (iArg1+iArg2);    
}    

2.制作靜態(tài)庫(kù)文件

1.編譯并生成目標(biāo)文件:gcc -c myAddLib.c -o myAddLib.o
2.生成歸檔文件:ar -rc libmyAddlib.a myAddLib.o

gcc -o myAddLib.o -c myAddLib.c 

把源程序文件編譯成*.o。-c :只編譯并生成目標(biāo)文件兆龙。

ar -rc libmyAddLib.a myAddLib.o 

執(zhí)行完后會(huì)生成一個(gè)libmyAddLib.a 文件
-c create的意思
-r replace的意思,表示當(dāng)插入的模塊名已經(jīng)在庫(kù)中存在,則替換同名的模塊.如果若干模塊中有一個(gè)模塊在庫(kù)中不存在,ar顯示一個(gè)錯(cuò)誤消息,并不替換其他同名模塊.默認(rèn)的情況下,新的成員增加在庫(kù)的結(jié)尾處,可以使用其他任選項(xiàng)來(lái)改變?cè)黾拥奈恢谩?/p>

3.使用靜態(tài)庫(kù)文件

/*************************************************************     
    FileName : testAddLib.c 
    FileFunc : 測(cè)試靜態(tài)庫(kù)文件   
    Version  : V0.1     
    Author   : Sunrier     
    Date     : 2012-04-28 
    Descp    : Linux下實(shí)現(xiàn)靜態(tài)庫(kù)   
*************************************************************/  
#include <stdio.h>  
#include "myAddLib.h"  
  
int main(int argc,char *argv[])  
{  
        int iNumber1,iNumber2,iSum = 0;  
        iNumber1 = 10;  
        iNumber2 = 20;  
        iSum = add(iNumber1,iNumber2);  
        printf("iSum=%d\n".iSum);  
        printf("Hello Sunrier!\n");  
        return 0;  
}  

編譯:gcc -o testAddLib testAddLib.c -L. -lmyAddLib
-L指定庫(kù)路徑杖爽,-lmyAddLib指定庫(kù)的名稱,不包含lib.a兩部分紫皇。

第二節(jié):動(dòng)態(tài)函數(shù)庫(kù)

動(dòng)態(tài)函數(shù)庫(kù)又叫共享庫(kù)(share lib)慰安。它是在運(yùn)行時(shí),由系統(tǒng)的動(dòng)態(tài)函
數(shù)庫(kù)"lib/ld.so"負(fù)責(zé)動(dòng)態(tài)加載聪铺。
動(dòng)態(tài)函數(shù)庫(kù)也有自己的命名規(guī)則:lib+動(dòng)態(tài)庫(kù)名稱+.so+.+版本號(hào);比如libC++.so.6化焕。
動(dòng)態(tài)函數(shù)庫(kù)有兩種使用方式:動(dòng)態(tài)鏈接(隱式調(diào)用)和動(dòng)態(tài)調(diào)用(顯式調(diào)用,利用lib/ld.so提供的函數(shù)铃剔,利用函數(shù)指針撒桨,動(dòng)態(tài)調(diào)用一個(gè)類庫(kù)中包含的函數(shù),不需要知道動(dòng)態(tài)庫(kù)的頭文件)番宁。

隱式調(diào)用和顯示調(diào)用:

隱式調(diào)用使用方便簡(jiǎn)單, 但其和靜態(tài)庫(kù)相似, 在編譯期就和程序綁定了,靈活性差, 并且其生存期和進(jìn)程一樣, 進(jìn)程開(kāi)始, 調(diào)用開(kāi)始, 進(jìn)程結(jié)束, 動(dòng)態(tài)庫(kù)才卸載. 另外還需要將整個(gè)動(dòng)態(tài)庫(kù)全部加進(jìn)內(nèi)存.
顯式調(diào)用使用起來(lái)比較復(fù)雜, 但是卻可以在運(yùn)行期間選擇所需要調(diào)用的動(dòng)態(tài)鏈接庫(kù), 并且可以控制動(dòng)態(tài)庫(kù)生存期, 需要加載時(shí)候再加載, 用完了就可以卸掉, 而且不用將整個(gè)動(dòng)態(tài)庫(kù)都放進(jìn)內(nèi)存, 只要加載要用到的函數(shù)即可.

隱式調(diào)用:

編寫(xiě)動(dòng)態(tài)庫(kù)文件

/*************************************************************  
    FileName : myAddLib.h 
    FileFunc : 定義頭文件    
    Version  : V0.1     
    Author   : Sunrier     
    Date     : 2012-05-02 
    Descp    : Linux下實(shí)現(xiàn)動(dòng)態(tài)庫(kù)     
*************************************************************/  
#ifndef   _MYADDLIB_H_      
#define   _MYADDLIB_H_   
  
#ifdef __cplusplus  
extern "C" {  
#endif  

int add(int ,int );  

#ifdef __cplusplus  
}  
#endif  
  
#endif   
/*************************************************************     
    FileName : myAddLib.c 
    FileFunc : 定義動(dòng)態(tài)庫(kù)實(shí)現(xiàn)文件   
    Version  : V0.1     
    Author   : Sunrier     
    Date     : 2012-05-02 
    Descp    : Linux下實(shí)現(xiàn)動(dòng)態(tài)庫(kù)    
*************************************************************/  
#include <stdio.h>  
int add(int iArg1,int iArg2)  
{  
        printf("iArg1= %d , iAgr2= %d \n",iArg1,iArg2);  
        return (iArg1+iArg2);  
}  

制作庫(kù)文件:

1.gcc -fipc myAddLib.c -o myAddLib.o
2.gcc -share -o libmyAddLib.so.1 myAddlib.o
或者 gcc -fipc -share -o libmyAddLib.so.1 myAddLib.c
其中-fipc用來(lái)產(chǎn)生和位置無(wú)關(guān)代碼元莫,-share用來(lái)生成動(dòng)態(tài)共享庫(kù)

隱式使用動(dòng)態(tài)庫(kù)文件
/*************************************************************     
    FileName : testAddLib.c 
    FileFunc : 測(cè)試動(dòng)態(tài)庫(kù)文件   
    Version  : V0.1     
    Author   : Sunrier     
    Date     : 2012-05-02 
    Descp    : Linux下實(shí)現(xiàn)動(dòng)態(tài)庫(kù)   
*************************************************************/  
#include <stdio.h>  
#include "myAddLib.h"  
  
int main(int argc,char *argv[])  
{  
        int iNumber1,iNumber2,iSum = 0;  
        iNumber1 = 10;  
        iNumber2 = 20;  
        iSum = add(iNumber1,iNumber2);  
        printf("iSum=%d\n",iSum);  
        printf("Hello Sunrier!\n");  
        return 0;  
}  
編譯目標(biāo)文件
gcc -o testAddLib testAddLib.c -L. -lmyAddLib

-L指定動(dòng)態(tài)函數(shù)庫(kù)的位置供查找,注意L后面還有'.'蝶押,表示動(dòng)態(tài)函數(shù)庫(kù)在本目錄下查找踱蠢。此時(shí)還不能立即./testAddLib,因?yàn)樵趧?dòng)態(tài)函數(shù)庫(kù)使用時(shí),會(huì)查找/usr/lib或/lib目錄下的動(dòng)態(tài)函數(shù)庫(kù),而此時(shí)我們生成的庫(kù)不在里邊棋电。

執(zhí)行可執(zhí)行文件

這個(gè)時(shí)候有好幾種方法可以讓他成功運(yùn)行:
最直接最簡(jiǎn)單的方法就是把libmyAddLib.so放到/usr/lib或/lib中去或者修改LD_LIBRARY_PATH環(huán)境變量文件茎截。

假設(shè)libmyAddLib.so在/home/Sunrier/lib  
export LD_LIBRARY_PATH=/home/Sunrier/lib:$LD_LIBRARY_PATH  

另外還可以在/etc/ld.so.conf文件里加入我們生成的庫(kù)的目錄,然后/sbin/ldconfig赶盔。
/etc/ld.so.conf是非常重要的一個(gè)配置文件企锌,里面存放的是鏈接器和加載器搜索共享庫(kù)時(shí)要檢查的目錄,默認(rèn)是從/usr/lib或/lib中讀取的,所以想要順利運(yùn)行,我們也可以把我們庫(kù)的目錄加入到這個(gè)文件中并執(zhí)行/sbin/ldconfig。

動(dòng)態(tài)調(diào)用:

根據(jù)前面提到的生成頭文件libmyAddLib.so文件于未。

/*************************************************************     
    FileName : testAddLib.c 
    FileFunc : 測(cè)試動(dòng)態(tài)庫(kù)文件   
    Version  : V0.1     
    Author   : Sunrier     
    Date     : 2012-05-03 
    Descp    : Linux下實(shí)現(xiàn)動(dòng)態(tài)庫(kù)   
*************************************************************/  
#include <stdio.h>  
#include <dlfcn.h>  
  
#define SOFILE "./libmyAddLib.so"  
  
int main(int argc,char *argv[])  
{  
        int iNumber1,iNumber2,iSum = 0;  
  
        void *hdl = NULL;//動(dòng)態(tài)庫(kù)句柄   
          hdl = dlopen(SOFILE,RTLD_LAZY);//打開(kāi)動(dòng)態(tài)鏈接庫(kù)  
          if( NULL==hdl )  
        {  
             printf("No libmyAddLib.so file\n");  
             return 1;  
        }  
        /*函數(shù)指針*/  
        int(*add)(int,int);  
        add = dlsym(hdl,"add");//查找符號(hào)表,定位共享函數(shù)  
          char *error = dlerror();//檢測(cè)錯(cuò)誤  
          if( error )  
        {  
            printf("No function!\n");  
            return 1;  
        }  
        iNumber1 = 10;  
        iNumber2 = 20;  
        iSum = add(iNumber1,iNumber2);//調(diào)用此共享函數(shù)  
          //iSum = (*add)(iNumber1,iNumber2);//調(diào)用此共享函數(shù)  
          printf("iSum=%d\n",iSum);  
        printf("Hello Sunrier!\n");  
        dlclose(hdl);//關(guān)閉共享庫(kù)  
          hdl =NULL;  
        return 0;  
}  

dlfcn.h包含了動(dòng)態(tài)調(diào)用函數(shù)庫(kù)的相關(guān)的函數(shù)撕攒。

void  *dlopen (const char *file, int arg );  
//打開(kāi)一個(gè)動(dòng)態(tài)庫(kù)的文件,arg代表打開(kāi)的方式  
/* 
RTLD_LAZY 
Relocations are performed at an implementation-dependent time. 
RTLD_NOW 
Relocations are performed when the object is loaded. 
RTLD_GLOBAL 
All symbols are available for relocation processing of other modules. 
RTLD_LOCAL 
All symbols are not made available for relocation processing by other modules.*/  

void *dlsym(void *handle, const char *name);  
  
void    *handle;  
int     *iptr, (*fptr)(int);  
  
/* open the needed object */  
handle = dlopen("/usr/home/me/libfoo.so.1", RTLD_LAZY);  
  
/* find the address of function and data objects */  
fptr = (int (*)(int))dlsym(handle, "my_function");  
iptr = (int *)dlsym(handle, "my_object");  
  
/* invoke function, passing value of integer as a parameter */  
(*fptr)(*iptr);  

char *dlerror(void);  
/*If successful, dlerror() returns a null-terminated character string. Otherwise, NULL is returned.*/  

int dlclose(void *handle);  
/*If the referenced object was successfully closed, dlclose() returns 0.   

If the object could not be closed, or if handle does not refer to an open object,   
dlclose() returns a non-zero value. More detailed diagnostic information will be available through dlerror().*/  
編譯和生成目標(biāo)文件:
#gcc testAddLib.c -o testAddLib -ldl

其中-ldl用于加載dl庫(kù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末烘浦,一起剝皮案震驚了整個(gè)濱河市抖坪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌闷叉,老刑警劉巖擦俐,帶你破解...
    沈念sama閱讀 211,376評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異握侧,居然都是意外死亡蚯瞧,警方通過(guò)查閱死者的電腦和手機(jī)嘿期,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)埋合,“玉大人备徐,你說(shuō)我怎么就攤上這事〖玻” “怎么了坦喘?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,966評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)西设。 經(jīng)常有香客問(wèn)我,道長(zhǎng)答朋,這世上最難降的妖魔是什么贷揽? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,432評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮梦碗,結(jié)果婚禮上禽绪,老公的妹妹穿的比我還像新娘。我一直安慰自己洪规,他們只是感情好印屁,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著斩例,像睡著了一般雄人。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上念赶,一...
    開(kāi)封第一講書(shū)人閱讀 49,792評(píng)論 1 290
  • 那天础钠,我揣著相機(jī)與錄音,去河邊找鬼叉谜。 笑死旗吁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的停局。 我是一名探鬼主播很钓,決...
    沈念sama閱讀 38,933評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼董栽!你這毒婦竟也來(lái)了码倦?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,701評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤裆泳,失蹤者是張志新(化名)和其女友劉穎叹洲,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體工禾,經(jīng)...
    沈念sama閱讀 44,143評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡运提,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評(píng)論 2 327
  • 正文 我和宋清朗相戀三年蝗柔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片民泵。...
    茶點(diǎn)故事閱讀 38,626評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡癣丧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出栈妆,到底是詐尸還是另有隱情胁编,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評(píng)論 4 329
  • 正文 年R本政府宣布鳞尔,位于F島的核電站嬉橙,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏寥假。R本人自食惡果不足惜市框,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望糕韧。 院中可真熱鬧枫振,春花似錦、人聲如沸萤彩。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)雀扶。三九已至杖小,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間怕吴,已是汗流浹背窍侧。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留转绷,地道東北人伟件。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像议经,于是被迫代替她去往敵國(guó)和親斧账。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容