程序編譯鏈接(六)-- 動態(tài)鏈接顯示運(yùn)行時鏈接

支持動態(tài)鏈接的系統(tǒng)往往都支持一種更加靈活的模塊加載方式恩伺,叫做顯示運(yùn)行時鏈接徙瓶,有時候也叫做運(yùn)行時加載。
這種運(yùn)行時加載使得程序的模塊組織變得很靈活,可以用來實(shí)現(xiàn)一些諸如插件罕伯,驅(qū)動等功能。當(dāng)程序需要用到某個插件或者驅(qū)動的時候髓梅,才將相應(yīng)的模塊裝載進(jìn)來,而不是需要從一開始就將他們?nèi)垦b載進(jìn)來绎签,從而少了程序啟動時間和內(nèi)存使用枯饿。并且程序在運(yùn)行的時候重新加載某個模塊,這樣使得程序本身不必重新啟動而實(shí)現(xiàn)模塊的增加诡必,刪除奢方,更新等。

在Linux中,而動態(tài)庫的裝載則是通過一系列的API提供:dlopen蟋字, dlsym稿蹲,dlerrordclose鹊奖。

dlopen

dlopen函數(shù)負(fù)責(zé)打開一個動態(tài)庫苛聘,并將其加載到進(jìn)程進(jìn)程的地址空間,完成初始化過程忠聚。

void* dlopen(const char* filename, int flag);
  • 第一個參數(shù)
    第一個參數(shù)是被加載動態(tài)庫的路徑焰盗,如果整個路徑是絕對路徑,則該函數(shù)將會嘗試直接打開該動態(tài)庫咒林,如果是相對路徑,那么將會按照下面的順序查找:

    1. 查找有環(huán)境變量LD_LIBRARY_PATH指定的一系列目錄
    2. 查找由/etc/ld.so.cache里面所指定的共享庫路徑
    3. /lib爷光,/usr/lib
  • 第二個參數(shù)
    表示函數(shù)符號的解析方式:

    • RTLD_LAZY
      表示使用延遲綁定垫竞,
    • RTLD_NOW
  • 返回值
    dlopen的返回值是被加載模塊的句柄,如果加載失敗則返回NULL蛀序。

dlsym
void* dlsym(void* handle, char *symbol);
  • 第一個參數(shù)
    dlopen返回的動態(tài)庫的句柄欢瞪。
  • 第二個參數(shù)
    即要查找的符號的名字。
  • 返回值
    如果dlsym找到了相應(yīng)的符號徐裸,則返回該符號的值遣鼓,如果查找的符號是一個函數(shù),則返回函數(shù)的地址重贺;
    如果是一個變量骑祟,則返回變量的地址。
    如果整個符號是一個常量气笙,那么返回的是該常量的值次企。
dlerror

每次調(diào)用以后,都可以調(diào)用dlerror函數(shù)來判斷上一次調(diào)用是否成功潜圃。

dlclose

dlclose的作用和dlopen相反缸棵,它的作用是將一個已經(jīng)加載的模塊卸載,系統(tǒng)會維持一個加載的引用計(jì)數(shù)器谭期,每次使用dlopen加載模塊時堵第,相應(yīng)的計(jì)數(shù)器加1,每次使用dlclose卸載模塊時隧出,相應(yīng)計(jì)數(shù)器減1踏志,只有當(dāng)計(jì)數(shù)器值減少到0時,模塊才真正被卸載掉胀瞪。

例子
#include <stdio.h>
#include <dlfcn.h>

int main(int argc, char **argv)
{
    void* handler;
    double (*func)(double);
    char* error;

    handler = dlopen(argv[1], RTLD_NOW);
    if (handler == NULL) {
        printf("Open library %s error: %s\n %s\n", argv[1], dlerror());
        return -1;
    }

    func = dlsym(handler, "sin");
    if ( (error = dlerror()) != NULL ) {
        printf("Symbol sin not found: %s\n", error);
        goto exit_runso;
    }

    printf("%f\n", func(3.1415926 / 2));

exit_runso:
    dlclose(handler);
}
# gcc RunSoSimple.c -o RunSoSimple -ldl  # -ldl 表示使用DL(Dynamical Loading)庫
# ./RunSoSimple /lib64/libm-2.17.so
1.000000
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末狰贯,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌涵紊,老刑警劉巖傍妒,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異摸柄,居然都是意外死亡颤练,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門驱负,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嗦玖,“玉大人,你說我怎么就攤上這事跃脊∮畲欤” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵酪术,是天一觀的道長器瘪。 經(jīng)常有香客問我,道長绘雁,這世上最難降的妖魔是什么橡疼? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮庐舟,結(jié)果婚禮上欣除,老公的妹妹穿的比我還像新娘。我一直安慰自己挪略,他們只是感情好历帚,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著杠娱,像睡著了一般抹缕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上墨辛,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天卓研,我揣著相機(jī)與錄音,去河邊找鬼睹簇。 笑死奏赘,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的太惠。 我是一名探鬼主播磨淌,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼凿渊!你這毒婦竟也來了梁只?” 一聲冷哼從身側(cè)響起缚柳,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎搪锣,沒想到半個月后秋忙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡构舟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年灰追,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狗超。...
    茶點(diǎn)故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡弹澎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出努咐,到底是詐尸還是另有隱情苦蒿,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布渗稍,位于F島的核電站佩迟,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏免胃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一惫撰、第九天 我趴在偏房一處隱蔽的房頂上張望羔沙。 院中可真熱鬧,春花似錦厨钻、人聲如沸扼雏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽诗充。三九已至,卻和暖如春诱建,著一層夾襖步出監(jiān)牢的瞬間蝴蜓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工俺猿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留茎匠,地道東北人。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓押袍,卻偏偏與公主長得像诵冒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子谊惭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評論 2 355

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