16

例如:

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 导出的任何其他符号。

4

5 回答 5

16

没有 libc 函数可以做到这一点。但是,您可以自己编写一个(尽管代码有些涉及)。

在 Linux 上,dlopen()实际上返回一个link_map结构的地址,该结构有一个名为的成员,该成员l_addr指向加载的共享对象的基地址(假设您的系统没有随机化共享库的位置,并且您的库没有被预链接)。

在 Linux 上,找到基地址( 的地址Elf*_Ehdr)的可靠方法是在ing 库dl_iterate_phdr()之后使用。dlopen()

有了 ELF 标头,您应该能够遍历导出符号列表(动态符号表),首先定位Elf*_Phdrtype PT_DYNAMIC,然后定位DT_SYMTAB,DT_STRTAB条目并遍历动态符号表中的所有符号。用来/usr/include/elf.h指导你。

此外,您可以使用libelf,但我无法指导您,因为我以前没有使用它的经验。

最后请注意,该练习有些徒劳:您将获得已定义函数的列表,但您不知道如何调用它们(它们期望什么参数),那么重点是什么?

于 2010-04-22T20:50:58.487 回答
1

我认为没有为此发布的 API。您可以使用 binutils 中的 nm 工具或检查其源代码: http: //sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/ ?cvsroot=src

http://sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/nm.c?rev=1.63&content-type=text/x-cvsweb-markup&cvsroot=src

(显然假设精灵)

于 2010-04-22T20:50:31.983 回答
0

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.dynsym

于 2020-06-29T17:00:07.900 回答
-3

可以使用linux nm命令: http://man.yolinux.com/cgi-bin/man2html ?cgi_command=nm

于 2015-02-24T18:02:36.760 回答
-3
void *dlsym(void *restrict handle, const char *restrict name);

返回值

如果句柄不引用由dlopen()打开的有效对象,或者如果在与句柄关联的任何对象中都找不到命名符号 ,则dlsym()应返回 NULL。应通过dlerror()获得更详细的诊断信息。

(来源:http ://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html )

换句话说,如果找不到符号,dlsym()将返回NULL. 不确定这是否是您要寻找的,但这是我能找到的最简单的方法。

于 2010-04-22T20:43:53.383 回答