亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 操作系統 > 正文

靜態鏈接庫、動態鏈接庫和動態加載庫

2024-06-28 13:27:40
字體:
來源:轉載
供稿:網友
靜態鏈接庫、動態鏈接庫和動態加載庫

靜態鏈接庫

前言

靜態庫是obj文件的一個集合(目標文件中通常僅解析了文件內部的變量和函數,對于引用的函數和變量還沒有解析,這需要將其他已經編寫好的目標文件引用進來,將沒有解析的函數和變量進行解析,通常引用的目標是庫),通常靜態庫以".a"為后綴,名字格式一般為libxxx.a靜態庫由程序ar生成。

實例程序如下:

Main.c

#include <stdio.h>

extern void PRint_hello();

int

main(void)

{

print_hello();

}

Print_hello.c

#include <stdio.h>

void

print_hello()

{

printf("hello/n");

}

  1. 生成靜態鏈接庫

    創建靜態庫的步驟:

    1. 生成目標文件。(使用命令gcc –c file.c)
    2. 使用工具ar對目標文件進行歸檔。(使用的命令如下)

    生成靜態鏈接庫,或者將一個obj文件加入到已經存在的靜態庫的命令格式為:

    ar –rcs 庫文件obj_1 obj_2 …

    使用上面的實例程序print_hello.c創建靜態鏈接庫:

  2. 使用靜態鏈接庫

    使用方式一:

    使用方式二:

    注意,在方法二中"-L./"不可少,否則出現如下錯誤:

    這是因為上面的命令在系統默認的路徑下查找hello函數庫,而我們并沒有將libhello.a庫放在系統默認搜索路徑下,所以需要顯示指定庫函數的路徑為當前目錄。

    另外還需注意,在使用-l選項時,-o選項的目標名稱要在-l鏈接的庫名稱之前,否則gcc會認為-l是生成的目標而出錯。

    下面兩個圖分別是頭文件和庫文件的默認搜索路徑:

動態鏈接庫

前言

動態鏈接庫是程序運行時加載的庫,當動態鏈接庫正確安裝后,所有的 程序都可以使用動態庫來運行程序。動態鏈接庫是目標文件的集合,目標文件在動態鏈接庫中的組織方式是按照特殊方式形成的。庫中函數和變量的地址是相對地址,不是絕對地址,其真實地址在調用動態庫的程序加載時形成。

動態鏈接庫的名稱有別名(soname)、真名(realname)和鏈接名(linker name):

別名:libxxx.so,這種形式的庫名正是執行編譯命令時編譯器要搜索的名字。

真名:動態鏈接庫的真實名稱,一般總是在別名的基礎上加上一個小版本號、發布版本等構成。

鏈接名:程序鏈接時使用的庫的名字。

  1. 生成動態鏈接庫

    生成動態鏈接庫的命令很簡單,使用-fPIC選項或者-fpic選項。-fPIC和-fpic選項的作用是使得gcc生成的代碼是位置無關的,例如下面的命令將print_hello.c編譯生成動態鏈接庫:

    其中-shared選項告訴編譯器生成一個動態鏈接庫;-soname,libhello.so表示生成動態庫的別名是libhello.so;-o libhello.so.1選項擇表示生成名字為libhello.so.1的實際動態鏈接庫文件。

    生成動態鏈接庫之后一個很重要的問題就是安裝,一般情況下將生成的動態鏈接庫復制到系統默認的動態鏈接庫的搜索路徑下,通常有/lib,/usr/lib,/usr/local/lib,放到其中任何一個目錄下都可以。

  2. 動態鏈接庫的配置

    動態鏈接庫并不是可以隨意地使用,要在運行的 程序中使用動態鏈接庫,需要指定系統的動態鏈接庫搜索的路徑,讓系統找到運行所需要的動態鏈接庫才可以。

    系統中的配置文件/etc/ld.so.conf是動態鏈接庫的搜索路徑配置文件。這這個文件內,存放著可被linux共享的動態鏈接庫所在目錄的名字系統目錄/lib,/usr/lib除外,這兩個目錄默認就是動態鏈接庫的搜索路徑),多個目錄名間以空白字符(空格、換行等)或冒號或逗號分割。查看系統中的動態鏈接庫配置文件的內容:

    Linux的配置文件將目錄ld.so.conf.d/中的配置文件包含了進來。

  3. 動態鏈接庫管理命令

    為了讓新增加的動態鏈接庫能夠被系統共享,需要運行動態鏈接庫的 管理命令ldconfig。ldconfig命令的作用是在系統的默認搜索路徑和動態鏈接庫配置文件中所列出的目錄里搜索動態鏈接庫,創建動態鏈接庫裝入程序需要的鏈接和緩存文件。搜索完畢后,將結果寫入緩存文件/etc/ld.so.cache中,文件中保存的是已經排好序的動態鏈接庫名字列表。

    ldconfig命令的用法如下:

  4. 使用動態鏈接庫

把當前工作目錄(libhello.so.1所在的目錄)加入動態鏈接庫的搜索路徑配置文件/etc/ld.so.conf中

執行ldconfig命令刷新緩存文件/etc/ld.so.cache:

我們會發現,執行ldconfig命令后,當前目錄下生成了一個新的文件libhello.so(這是-soname,libhello.so選項導致的,如果沒有該選項,那么ldconfig執行后不會生成新文件libhello.so。),使用ls命令會發現此文件是libhello.so.1的鏈接文件:

在編譯程序時,使用動態鏈接庫和靜態鏈接庫是一致的,使用"-lxxx"的方式:

編譯后執行時出現如下錯誤:

其主要原因是使用了SELINUX。將其狀態設置為disabled即可,方法如下:打開/etc/selinux/config,將selinux=enforcing或permissive改成disabled。然后存盤退出,重啟系統。

再次執行,結果如下:

運行時,還可能出現這樣的錯誤:test: error while loading shared libraries: libxxx.so: cannot open shared object file: No such file or directory,這是由于程序運行時沒有找到動態鏈接庫造成的。程序編譯時鏈接動態鏈接庫和運行時使用動態鏈接庫的概念是不同的,在運行時,程序鏈接的動態鏈接庫需要在系統目錄下才行。有幾種辦法可以解決此種問題:

  1. 將動態鏈接庫的目錄放到程序搜索路徑中,可以將庫的路徑添加到環境變量LD_LIBRARY_PATH中實現:

  1. 使用ld-Linux.so.2來加載程序,命令格式為:

/lib/ ld-Linux.so.2 –library-path 路徑 程序名

加載test程序的命令為:

不過貌似并不是所有系統上都有ld-Linux.so.2。

注意,如果系統的搜索路徑下同時存在靜態鏈接庫和動態鏈接庫,默認情況下會鏈接動態鏈接庫。如果需要強制鏈接靜態鏈接庫,需要加上"-satic"選項。

動態加載庫

前言

動態加載庫和一般的動態鏈接庫所不同的是,一般動態鏈接庫在程序啟動時就要尋找動態庫,找到庫函數;而動態加載庫可以用程序的方法來控制什么時候加載。動態加載庫主要有函數dlopen()、dlerror()、dlsym()和dlclose()來控制動態庫的使用。函數原型如下:

  1. 打開動態庫dlopen()

    函數dlopen()按照用戶指定的方式打開動態鏈接庫,其中參數filename為動態鏈接庫的文件名,flag為打開方式,一般為RTLD_LASY,函數的返回值為庫的指針。

    例如,下面的代碼使用dlopen打開當前目錄下的動態庫libhello.so:

    void *phandle = dlopen("./libhello.so", RTLD_LAZY);

  2. 獲得函數指針dlsym()

    使用動態鏈接庫的目的是調用其中的函數,完成特定的功能。函數dlsym()可以獲得動態鏈接庫中指定函數的指針,然后可以使用這個函數指針進行操作。其中參數handle為dlopen()打開動態庫后返回的句柄,參數symbol為函數的名稱,返回值為函數指針。

  3. 使用動態加載庫實例

    #include <stdio.h>

    #include <dlfcn.h>

    int

    main(void)

    {

    void (*printhello)(void);

    void *phandle = NULL;

    char *perr = NULL;

    phandle = dlopen("./libhello.so", RTLD_LAZY);

    if(!phandle)

    {

    printf("Failed load library!/n");

    }

    perr = dlerror();

    if(perr != NULL)

    {

    printf("%s/n", perr);

    return(0);

    }

    printhello = dlsym(phandle, "print_hello");

    perr = dlerror();

    if(perr != NULL)

    {

    printf("%s/n", perr);

    return(0);

    }

    (*printhello)();

    dlclose(phandle);

    return(0);

    }

    編譯運行:

    注意,想要使用dlfcn.h中的函數,編譯時必須加上選項-ldl。

小發現:

  有沒有注意到,我們并沒有使用用到include <hello.h>(假設我們為print_hello.c寫了一個hello.h的頭文件)。其實,只要編譯命令中加入選項-lhello,hello.h頭文件包含不包含都沒有問題。為了驗證這個問題,使用http://www.CUOXin.com/nufangrensheng/p/3518411.html中的程序清單11-1這個實例進行了測試:

  在http://www.CUOXin.com/nufangrensheng/p/3518411.html程序清單11-1編譯過程中,曾遇到undefined reference to ‘pthread_create’這樣的錯誤,原因在于沒有在編譯命令中加入-lpthread選項。

  如果我們加入了-lpthread選項,此時嘗試著把程序中的#include <pthread.h>去掉,重新編譯你會發現同樣也是可以的。

  總結:如果使用的是標準庫中的函數,則只需將頭文件包含進來。如果使用的函數所在的庫不是標準庫(例如我們自己編寫的庫或標準以外擴展的庫),則在編譯時必須加入-lxxx選項,而頭文件則可以包含也可以不包含,包含進來顯得規范而已。

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲免费av电影| 久久天堂电影网| 亚洲日本成人女熟在线观看| 欧美—级a级欧美特级ar全黄| zzijzzij亚洲日本成熟少妇| 亚洲第一二三四五区| 亚洲高清久久久久久| 久久久久国产精品免费| 久久精品国产亚洲精品2020| 97在线视频免费播放| 国产精品成人aaaaa网站| 国产精品视频26uuu| 色琪琪综合男人的天堂aⅴ视频| 国产精品久久久久久久美男| 色综合色综合久久综合频道88| 欧美大片欧美激情性色a∨久久| 国产精品网红福利| 欧美电影免费在线观看| 国内精品视频一区| 国产精品成人一区二区三区吃奶| 国产+成+人+亚洲欧洲| 亚洲自拍av在线| 日韩中文综合网| 欧美午夜女人视频在线| 精品亚洲男同gayvideo网站| 91在线色戒在线| 国产精品精品国产| 久久99精品久久久久久青青91| 国产精品久久久久久av| 国产精品一区二区三区成人| 另类专区欧美制服同性| 26uuu国产精品视频| 精品亚洲国产成av人片传媒| 亚洲自拍偷拍福利| 欧美巨猛xxxx猛交黑人97人| 成人高清视频观看www| 一区三区二区视频| 欧洲精品在线视频| 91国在线精品国内播放| 亚洲aa在线观看| 日韩精品高清在线观看| 日韩视频免费在线观看| 日韩黄色高清视频| 亚洲精品久久在线| 欧美性xxxx极品hd满灌| 国产精品嫩草影院一区二区| 孩xxxx性bbbb欧美| 欧美大学生性色视频| 亚洲综合色激情五月| 国产欧美日韩中文| 奇米影视亚洲狠狠色| 精品福利樱桃av导航| 欧美久久精品午夜青青大伊人| 亚洲在线观看视频网站| 欧美亚洲在线视频| 亚洲精品久久久久久久久久久久久| 亚洲精品国精品久久99热一| 欧美性猛交xxxxx水多| 日韩精品免费电影| 深夜成人在线观看| 在线中文字幕日韩| 91精品免费久久久久久久久| 亚洲高清av在线| 亚洲精品国产欧美| 这里只有精品视频| 久久久久久久久久国产| 日韩av黄色在线观看| 欧美亚洲伦理www| 欧美性极品少妇精品网站| 美女国内精品自产拍在线播放| 国产97在线|亚洲| 伊人久久综合97精品| 亚洲欧美一区二区三区久久| 国产国语videosex另类| 亚洲网址你懂得| 日韩视频在线免费观看| 粉嫩av一区二区三区免费野| 国产精品久久久久久av福利软件| 国产精品一区二区久久精品| 免费不卡欧美自拍视频| 亚洲视频在线观看视频| 久久福利视频导航| 国产精品成熟老女人| 欧美人在线观看| 亚洲天堂视频在线观看| 久久久亚洲精品视频| 精品久久久在线观看| 国产丝袜精品第一页| 91亚洲国产成人精品性色| 亚洲欧美日韩国产中文| 久久久女女女女999久久| 久久久国产视频91| 日韩精品久久久久久久玫瑰园| 成人黄色av免费在线观看| 色综合久久精品亚洲国产| 国产精品久久久久高潮| 欧美日韩国产成人高清视频| 亚洲一区二区三区乱码aⅴ蜜桃女| 欧美一区三区三区高中清蜜桃| 91精品国产高清自在线看超| 亚洲最大成人在线| 亚州精品天堂中文字幕| 亚洲伊人一本大道中文字幕| 欧美国产欧美亚洲国产日韩mv天天看完整| 国产日本欧美一区二区三区在线| 欧美—级a级欧美特级ar全黄| 91亚洲人电影| 欧美美女18p| 97精品视频在线播放| 日韩在线精品一区| 国产成人精品日本亚洲| 色妞欧美日韩在线| 国模精品一区二区三区色天香| 国产精品久久一区主播| 最近2019年中文视频免费在线观看| 国产精品网站大全| 91免费在线视频网站| 深夜精品寂寞黄网站在线观看| 国内精久久久久久久久久人| 久久久久久久香蕉网| 成人黄色av免费在线观看| 亚洲最大成人在线| 久久久久亚洲精品国产| www.日韩视频| 在线观看精品自拍私拍| 日韩高清av一区二区三区| 日韩欧美一区二区三区久久| 国产精品一香蕉国产线看观看| 国产国产精品人在线视| 国产欧美最新羞羞视频在线观看| 国产91免费观看| 久久中文字幕视频| 欧美电影在线免费观看网站| 国产精品久久国产精品99gif| 97热在线精品视频在线观看| 国产一区二区三区日韩欧美| 欧美二区在线播放| 日韩中文字幕视频在线| 久久精品亚洲精品| 国产精品va在线播放我和闺蜜| 成人国产精品免费视频| 一区三区二区视频| 九九热在线精品视频| 亚洲四色影视在线观看| 亚洲第一页自拍| 欧美中文字幕第一页| 欧美韩国理论所午夜片917电影| 91欧美日韩一区| 97人人爽人人喊人人模波多| 欧美激情女人20p| 国产精品高清免费在线观看| 亚洲深夜福利在线| 国产精品av免费在线观看| 亚洲成人av资源网| 伊人久久综合97精品| 成人国产精品日本在线| 日韩精品免费在线观看| 国产精品美女在线| 午夜美女久久久久爽久久| 最新69国产成人精品视频免费| 91成人精品网站| 国产精品成人久久久久| 九九热视频这里只有精品| 一区二区三区在线播放欧美|