Возврат таблицы символов общей библиотеки
Например:
void* sdl_library = dlopen("libSDL.so", RTLD_LAZY);
void* initializer = dlsym(sdl_library,"SDL_Init");
При условии отсутствия ошибок инициализатор укажет на функцию SD_Init в общей библиотеке libSDK.so.
Однако для этого необходимо знать, что существует символ "SDL_Init".
Возможно ли запросить библиотеку для всех ее символов? Например, в этом случае он вернул бы SDL_Init, указатель на функцию и любые другие символы, экспортированные libSDL.so.
4 ответа
Для этого нет функции libc. Тем не менее, вы можете написать один самостоятельно (хотя код несколько сложен).
В Linux dlopen()
фактически возвращает адрес link_map
структура, в которой есть член с именем l_addr
это указывает на базовый адрес загруженного разделяемого объекта (при условии, что ваша система не рандомизирует размещение разделяемой библиотеки, и что ваша библиотека не была предварительно связана).
В Linux верный способ найти базовый адрес (адрес Elf*_Ehdr
) использовать dl_iterate_phdr()
после dlopen()
в библиотеке.
Имея заголовок ELF, вы должны иметь возможность перебирать список экспортируемых символов (динамическую таблицу символов), сначала найдя Elf*_Phdr
типа PT_DYNAMIC
, а затем найти DT_SYMTAB
, DT_STRTAB
записи и итерации по всем символам в таблице динамических символов. использование /usr/include/elf.h
чтобы направлять вас.
Кроме того, вы можете использовать libelf, но я не могу вам помочь, поскольку у меня нет предыдущего опыта работы с ним.
В заключение отметим, что упражнение несколько бесполезно: вы получите список определенных функций, но вы не будете знать, как их вызывать (какие параметры они ожидают), так какой смысл?
Я не думаю, что есть опубликованный API для этого. Вы можете использовать инструмент nm из binutils или изучить его исходный код: 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
раздел. Похоже, что некоторые библиотеки не экспортируют символы в этом разделе. Я открыл запрос функции для поддержки возврата к.dynsym
раздел в таком случае.
Можно использовать команду linux nm: http://man.yolinux.com/cgi-bin/man2html?cgi_command=nm
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
, Не уверен, что это то, что вы ищете, но это самый простой способ, который я могу найти.