[英]Returning a shared library symbol table
例如:
void* sdl_library = dlopen("libSDL.so", RTLD_LAZY);
void* initializer = dlsym(sdl_library,"SDL_Init");
假設沒有錯誤,初始化程序將指向共享庫 libSDK.so 中的函數 SD_Init。
然而,這需要知道符號“SDL_Init”存在。
是否有可能查詢一個庫的所有符號? 例如,在這種情況下,它將返回 SDL_Init、函數指針和 libSDL.so 導出的任何其他符號。
沒有 libc 函數可以做到這一點。 但是,您可以自己編寫一個(盡管代碼有些涉及)。
在 Linux 上, dlopen()
實際上返回一個link_map
結構的地址,該結構有一個名為l_addr
的成員,指向加載的共享對象的基地址(假設您的系統沒有隨機化共享庫的位置,並且您的庫具有未預鏈接)。
在 Linux 上,找到基地址( Elf*_Ehdr
的地址)的Elf*_Ehdr
是在dlopen()
庫之后使用dl_iterate_phdr()
。
有了 ELF 標頭,您應該能夠遍歷導出的符號列表(動態符號表),首先定位Elf*_Phdr
類型的Elf*_Phdr
PT_DYNAMIC
,然后定位DT_SYMTAB
、 DT_STRTAB
條目,並迭代所有符號動態符號表。 使用/usr/include/elf.h
來指導您。
此外,您可以使用libelf ,但我無法指導您,因為我以前沒有使用它的經驗。
最后請注意,這個練習有點徒勞:您將獲得一個已定義函數的列表,但您不知道如何調用它們(它們期望什么參數),那么有什么意義呢?
我認為沒有為此發布的 API。 您可以使用 binutils 中的 nm 工具或檢查其源代碼: http : //sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/? cvsroot=src
(顯然假設精靈)
Boost.DLL通過library_info::symbols
函數提供此功能。 改編自有關查詢符號庫的教程:
// Class `library_info` can extract information from a library
boost::dll::library_info inf(libpath);
// Getting exported symbols
std::vector<std::string> exports = inf.symbols();
// Printing symbols
for (std::size_t j = 0; j < exports.size(); ++j) {
std::cout << exports[j] << std::endl;
}
請注意,這僅適用於nm
列出的沒有--dynamic
標志的符號,即.symtab
部分中的.symtab
。 似乎有些庫不導出該部分中的任何符號。 在這種情況下,我已經打開了一個功能請求以支持回.dynsym
部分。
void *dlsym(void *restrict handle, const char *restrict name);
返回值
如果handle不引用由dlopen()打開的有效對象,或者如果在與handle關聯的任何對象中找不到命名符號,則dlsym()應返回 NULL。 應通過dlerror()獲得更詳細的診斷信息。
(來源: http : //www.opengroup.org/onlinepubs/009695399/functions/dlsym.html )
換句話說,如果沒有找到符號, dlsym()
將返回NULL
。 不確定這是否是您要找的,但這是我能找到的最簡單的方法。
可以使用 linux nm命令: http : //man.yolinux.com/cgi-bin/man2html? cgi_command= nm
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.