Как получить адрес функции по имени? - PullRequest
4 голосов
/ 08 сентября 2011

Я бы хотел получить адрес функции по имени.

Например, в настоящее время я использую dlsym:

unsigned long get_func_addr(const char *func_name)
{
     return (unsigned long)dlsym(NULL, func_name);
}

Однако dlsym работает только для внешней функции. Это не будет работать для статической функции. Я знаю, что может быть несколько статических функций с одинаковыми именами в разных файлах. Но мне нужно по крайней мере получить адрес одной статической функции с именем. Когда-нибудь статическая функция будет встроена. Но это нормально, если файл C скомпилирован с отладкой. Я думаю, что с -g таблица символов статических функций присутствует, но как я могу получить к ней доступ?

Я не хочу создавать таблицу для сопоставления строки с адресом функции. Мне нужно найти способ сделать это динамически.

Ответы [ 3 ]

3 голосов
/ 08 сентября 2011

A static функция даже не должна существовать в двоичном файле, поэтому нет способа получить ее адрес. Даже если он существует, он мог быть изменен компилятором на основе знания того, что определенные аргументы могут принимать только определенные значения, или он мог изменить соглашение о вызовах таким образом, чтобы он не вызывался извне, и т. Д. убедитесь, что «настоящая» версия статической функции существует, если ее адрес сделан видимым для других модулей через указатель функции.

3 голосов
/ 08 сентября 2011

Это на самом деле невозможно без какого-либо создания какого-либо внешнего файла, который можно использовать для поиска ... например, как вы упоминали, таблица символов статических функций присутствует, но она генерируется при компиляции / время компоновки ... это не что-то доступное из не скомпилированного кода модуля.

Таким образом, вы можете генерировать и экспортировать таблицу символов как внешний файл из вашего скомпилированного и связанного исполняемого файла, а затем иметь функцию, которая динамически ищет имя функции во внешнем файле, которая предоставит информацию, необходимую для получения адреса. функции, в которой компилятор и компоновщик компилировали / связывали его.

0 голосов
/ 17 сентября 2011

Если необходимая функция, которую вы хотите найти, находится в DLL, вы можете использовать Windows API getprocaddress(), который принимает имя функции и имя DLL в качестве параметров.

Если вы хотите найти пользовательские функции, я бы рекомендовал использовать справочную таблицу, поскольку имена этих функций не сохраняются.

Для пользовательских функций вы можете заставить каждую функцию экспортировать свое имя в другую функцию при ее запуске. i.e.:

void my_func()
{
    register(my_func,"my_func");// the address and the name
    // ...
}

Таким образом, вы можете найти функцию позже по имени.

...