新聞中心
linux動(dòng)態(tài)庫(kù)教程:深入理解符號(hào)表

在Linux系統(tǒng)中,動(dòng)態(tài)鏈接庫(kù)(Dynamic Linking Library),簡(jiǎn)稱為動(dòng)態(tài)庫(kù),是一種可重用的軟件組件,被許多軟件應(yīng)用程序共享。一般情況下,動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)(Static Linking Library)是Linux系統(tǒng)中提供的兩種不同類型的庫(kù)。
使用靜態(tài)庫(kù)的程序在編譯的時(shí)候就已經(jīng)將庫(kù)函數(shù)鏈接到了可執(zhí)行文件中,而動(dòng)態(tài)庫(kù)可以在程序運(yùn)行的時(shí)候動(dòng)態(tài)地加載和鏈接。優(yōu)勢(shì)在于節(jié)約內(nèi)存空間和多個(gè)應(yīng)用程序之間共用同一份庫(kù)文件。
動(dòng)態(tài)庫(kù)在使用過(guò)程中需要用到符號(hào)表(Symbol Table),主要用于存儲(chǔ)函數(shù)和變量等符號(hào)在程序中的地址和鏈接信息。因此,深入理解動(dòng)態(tài)庫(kù)中的符號(hào)表對(duì)于程序員來(lái)說(shuō)是非常重要的。
一般情況下,ELF(Executable and Linkable Format)是Linux系統(tǒng)中用來(lái)存儲(chǔ)可執(zhí)行文件和共享庫(kù)等二進(jìn)制文件的標(biāo)準(zhǔn)格式。因此,深入理解符號(hào)表需要首先熟悉ELF二進(jìn)制格式。
ELF格式中主要包含兩種符號(hào)表:符號(hào)表(Symbol Table)和動(dòng)態(tài)符號(hào)表(Dynamic Symbol Table)。其中,符號(hào)表主要用于靜態(tài)鏈接,而動(dòng)態(tài)符號(hào)表則用于動(dòng)態(tài)鏈接。下面我們通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)演示符號(hào)表的使用方法。
代碼如下:
#include
void world() {
printf("world!\n");
}
void hello() {
printf("hello ");
world();
}
int main() {
hello();
return 0;
}
將上述代碼編譯成動(dòng)態(tài)鏈接庫(kù)的命令為:`gcc -shared -o libhello.so -fPIC hello.c`。
接下來(lái),我們編寫(xiě)一個(gè)使用動(dòng)態(tài)庫(kù)的程序。
代碼如下:
#include
#include
int main() {
void *handle;
void (*hello)();
char *error;
handle = dlopen("./libhello.so", RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
return 1;
}
hello = dlsym(handle, "hello");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error);
return 1;
}
hello();
dlclose(handle);
return 0;
}
運(yùn)行上述程序,輸出結(jié)果為:`hello world!`。
通過(guò)上述代碼我們可以看到,動(dòng)態(tài)庫(kù)的使用過(guò)程中主要采用dlfcn.h頭文件中的dlopen、dlsym和dlclose三個(gè)函數(shù)。
其中,dlopen函數(shù)用于打開(kāi)指定的共享庫(kù)文件,在本例中即為“./libhello.so”;dlsym函數(shù)用于獲取指定函數(shù)的地址,在本例中即為“hello”函數(shù);而dlclose函數(shù)用于關(guān)閉打開(kāi)的共享庫(kù)文件。
在Linux系統(tǒng)中,我們還可以使用objdump命令查看共享庫(kù)/可執(zhí)行文件中的符號(hào)表。命令格式為:`objdump -t `。
對(duì)于上述例子中生成的共享庫(kù)文件,我們運(yùn)行命令`objdump -t libhello.so`,得到以下輸出:
libhello.so: file format elf64-x86-64
SYMBOL TABLE:
0000000000000660 l d .note.gnu.build-id 0000000000000000 .note.gnu.build-id
0000000000000680 l d .gnu.hash 0000000000000000 .gnu.hash
00000000000006a0 l d .dynsym 0000000000000000 .dynsym
00000000000006e8 l d .dynstr 0000000000000000 .dynstr
0000000000000804 l d .eh_frame_hdr 0000000000000000 .eh_frame_hdr
0000000000000818 l d .eh_frame 0000000000000000 .eh_frame
0000000000201048 g D __bss_start 0000000000000000 _edata
0000000000201018 g D _edata 0000000000000000 _edata
0000000000201010 g D __data_start 0000000000000000 _edata
0000000000000678 g DF .text 0000000000000019 hello
000000000000068d g DF .text 0000000000000011 world
0000000000201010 g *ABS* 0000000000000000 base
通過(guò)對(duì)上述輸出的分析,我們可以了解到符號(hào)表中的一些基本信息。其中,以“l(fā)”開(kāi)始的行表示局部符號(hào),以“g”開(kāi)始的行表示全局符號(hào)。需要特別注意的是,函數(shù)名前面加上了“DF”,表示該符號(hào)是一個(gè)函數(shù)。在本例中,hello函數(shù)和world函數(shù)都是全局符號(hào)。
綜上,深入理解符號(hào)表是Linux動(dòng)態(tài)鏈接庫(kù)開(kāi)發(fā)中的重要一環(huán)。通過(guò)學(xué)習(xí)ELF二進(jìn)制格式和動(dòng)態(tài)庫(kù)的使用方法,以及了解符號(hào)表中存儲(chǔ)的相關(guān)信息,可以幫助我們更好地理解和開(kāi)發(fā)Linux系統(tǒng)中的動(dòng)態(tài)鏈接庫(kù)。
成都網(wǎng)站設(shè)計(jì)制作選創(chuàng)新互聯(lián),專業(yè)網(wǎng)站建設(shè)公司。
成都創(chuàng)新互聯(lián)10余年專注成都高端網(wǎng)站建設(shè)定制開(kāi)發(fā)服務(wù),為客戶提供專業(yè)的成都網(wǎng)站制作,成都網(wǎng)頁(yè)設(shè)計(jì),成都網(wǎng)站設(shè)計(jì)服務(wù);成都創(chuàng)新互聯(lián)服務(wù)內(nèi)容包含成都網(wǎng)站建設(shè),小程序開(kāi)發(fā),營(yíng)銷網(wǎng)站建設(shè),網(wǎng)站改版,服務(wù)器托管租用等互聯(lián)網(wǎng)服務(wù)。
網(wǎng)站題目:Linux動(dòng)態(tài)庫(kù)教程:深入理解符號(hào)表(linux動(dòng)態(tài)庫(kù)符號(hào)表)
網(wǎng)址分享:http://m.fisionsoft.com.cn/article/dpsipis.html


咨詢
建站咨詢
