Здесь у вас есть несколько подходов:
- Поскольку на него уже ответили комментарии @ user3386109 в комментариях к вопросу, вы можете отсканировать исходный файл и извлечь названия включенных функций.Это требует предварительной обработки файла (с
cpp(1)
), поскольку фактические имена функций могут быть скрыты в конструкциях макросов, а затем извлекать имена определений функций (для этого потребуется синтаксический анализатор или нет, в зависимости от ограничений, налагаемых на источникфайл, который вы хотите отсканировать).В любом случае, это будет сложная задача, и чем больше ограничений вы предполагаете для формата в исходном файле. - Вы можете
dlopen(3)
объектный файл (участвующая программа или общая библиотека) и сканироватьидентификаторы функций.Это также будет утомительно, поскольку вынуждает вас использовать двоичный формат (в основном, ELF), который будет использоваться в качестве целевой архитектуры вашей программы.Это зависит от исполняемого формата и не всегда будет возможно. Более простой подход - пометить эти идентификаторы в источнике (например, аннотации в java) макросом TAG, который расширяется до нуля, и пометитьместа, где будет происходить идентификатор функции.Например:
#define TAG
void TAG myFunc(int a, int b, int c)
Затем вы можете найти в файле TAG
и извлечь следующий идентификатор.
Язык Java требует, чтобы идентификаторы были включеныв исполняемом файле в строковом формате, так что вы можете применить самоанализ для получения этой информации, но это не является обязательным требованием в C / C ++.И вся структура иерархии классов также включена в исполняемый файл как статическая структура данных, так что вы можете перемещаться и открывать все иерархии типов Java.Это невозможно в C, поскольку основной целью программирования на C является эффективность.Наличие всей информации о типе, включенной в программу, вынуждает использовать много памяти для описания определений данных, и поэтому она не включена в C / C ++.
В любом случае, вы можете самостоятельно составить список с помощьюИдентификаторы имен, которые вы физически видите в файлах, так что, вероятно, вам даже не нужно автоматически обрабатывать ваши файлы во время сборки.
Еще один простой способ автоматически выполнить то, что вы запрашиваете, - это определить макрос:
#define FUNCTION_NAME(typ, name) char name##_string[] = #name; typ name
и используйте его как
FUNCTION_NAME(void, myFunc)(int par1, char *par2, int par3)
{
...
}
, который расширяется до
char myFunc_string[] = "myFunc";
void myFunc(int par1, char *par2, int par3)
{
...
}
, поэтому для каждой функции x
у вас будет статическая строка x_string
с именем в виде строки и заголовком функции, свободным от объявления того, что вы хотите (даже variadic func)
Кстати, внутри тела функции определен неявный макрос, который расширяется до строкисодержащий имя функции __func__
.Но проблема в том, что его можно использовать только внутри тела функции.