Получить указатель на текущую функцию в C (gcc)?

существует ли волшебная переменная в gcc содержание указателя на текущую функцию?

Я хотел бы иметь своего рода таблицу, содержащую для каждого указателя функции ряд информации.

Я знаю, что существует __ func __ переменная, содержащая название текущей функции как строка, но не как указатель функции.

Это не должно вызывать функцию затем, но только использоваться в качестве индекса.

ОТРЕДАКТИРУЙТЕ В основном, что я хотел бы сделать, способность выполнить вложенные функции непосредственно перед выполнением текущей функции (и также получение возврата для выполнения некоторых вещей.) В основном это похоже __ cyg_profile_func_enter и __ cyg_profile_func_exit (функции инструментария)... Но проблема состоит в том, что эти функции инструментария глобальны и не выделенные функции.

РЕДАКТИРОВАНИЕ В ядре Linux, можно использовать unsigned long kallsyms_lookup_name(const char *name) от include/linux/kallsyms.h ... Обратите внимание что CONFIG_KALLSYMS опция должна быть активирована.

12
задан LB40 9 February 2010 в 14:10
поделиться

11 ответов

Вот трюк, который получает адрес вызывающего абонента, его, вероятно, можно немного почистить. Получить значение метки можно с помощью расширения GCC GCC.

#include <stdio.h>

#define MKLABEL2(x) label ## x
#define MKLABEL(x) MKLABEL2(x)
#define CALLFOO do { MKLABEL(__LINE__): foo(&&MKLABEL(__LINE__));} while(0)

void foo(void *addr)
{
    printf("Caller address %p\n", addr);
}

int main(int argc, char **argv)
{
    CALLFOO;
    return 0;
}
1
ответ дан 2 December 2019 в 22:22
поделиться
void f() {
   void (*fpointer)() = &f;
}
6
ответ дан 2 December 2019 в 22:22
поделиться
#define FUNC_ADDR (dlsym(dlopen(NULL, RTLD_NOW), __func__))

и компиляция вашей программы, как

gcc -rdynamic -o foo foo.c -ldl
3
ответ дан 2 December 2019 в 22:22
поделиться

Если вы пошли на C ++, следующая информация может помочь вам:

набираются объекты, Функторы функции, завернутые в виде объектов, RTTI позволяет идентифицировать тип во время выполнения.

Функторы несут накладные расходы времени выполнения, и если это проблема для вас, я бы предложил жестко кодировать знания, используя кодовое поколение или использовать oo-heirarchy функторов.

1
ответ дан 2 December 2019 в 22:22
поделиться

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

Для принудительного использования действительного имени функции можно использовать макрос, который получает указатель на функцию, выполняет с ней какую-нибудь фиктивную операцию (например, присваивает ее временной переменной совместимого типа функции), чтобы проверить, что это действительно действительный идентификатор функции, а затем строчит (с #) имя функции, прежде чем она будет использована в качестве ключа.

UPDATE:

Я имею в виду что-то вроде:

typedef struct {
  char[MAX_FUNC_NAME_LENGTH] func_name;
  //rest of the info here
} func_info;

func_info table[N_FUNCS];

#define CHECK_AND_GET_FUNC_NAME(f) ({void (*tmp)(int); tmp = f; #f})

void fill_it()
{
  int i = -1;
  strcpy(table[++i].func_name, CHECK_AND_GET_FUNC_NAME(foo));
  strcpy(table[++i].func_name, CHECK_AND_GET_FUNC_NAME(bar));
  //fill the rest
}

void lookup(char *name) {
  int i = -1;
  while(strcmp(name, table[++i]));
  //now i points to your entry, do whatever you need
}

void foo(int arg) {
  lookup(__func__);
  //do something
}

void bar(int arg) {
  lookup(__func__);
  //do something
}

(код может нуждаться в некоторых исправлениях, я не пытался скомпилировать его, это просто чтобы проиллюстрировать идею)

.
2
ответ дан 2 December 2019 в 22:22
поделиться

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

Примечание. Если вы хотите сделать это, у вас должна быть последовательная схема именования параметра.

0
ответ дан 2 December 2019 в 22:22
поделиться

Если вы хотите сделать это в «обзоре», то вам следует использовать объекты, которые вы уже упоминали ( __ Cyg_profile_Func * ), так как это то, что они предназначены для Отказ Все остальное должно быть как специальное, что и ваш профиль.

Честно говоря, делая вещи общим способом (с фильтром), вероятно, меньше, если любой новый метод, который вы вставите на лету.

0
ответ дан 2 December 2019 в 22:22
поделиться

Вы можете захватить эту информацию с помощью SETJMP () . Поскольку он экономит достаточно информации, чтобы вернуться к вашей текущей функции, она должна включать эту информацию в предоставленной JMP_BUF .

Эта структура очень неотступна, но вы явно упоминаете GCC, так что это, вероятно, не проблема блокировки. См. Это пример GCC / X86 , чтобы понять, как он примерно работает.

0
ответ дан 2 December 2019 в 22:22
поделиться

Ответ, данный моим Мэдхупом, является правильным ответом. UITableViewController является подклассом UIViewController, поэтому добавление метода viewDidLoad в UITableViewController работает отлично.

-121--3759087-

Если вы не против специфичности для платформы, можно использовать system () call:

system("del index*.txt"); // DOS
system("rm index*.txt"); // unix

Вот некоторая документация по вызову system () , который является частью стандартной библиотеки C (cstdlib).

-121--3126650-

Если вы хотите создать код, я бы рекомендовал GSLGen от Imatix. Он использует XML для структурирования модели вашего кода, а затем простой PHP, такой как язык генерации сверху вниз, чтобы выплюнуть код - он был использован для генерации кода C.

Я лично крутился с lua, чтобы генерировать код.

0
ответ дан 2 December 2019 в 22:22
поделиться

Другой вариант, если переносимость не проблема, будет Настроить исходный код GCC ... Любые волонтеры?!

-1
ответ дан 2 December 2019 в 22:22
поделиться

Если вам нужен только уникальный идентификатор для каждой функции, то в начале каждой функции поставьте следующее:

static const void * const cookie = &cookie;

Значение cookie гарантированно будет значением, уникально идентифицирующим эту функцию.

-2
ответ дан 2 December 2019 в 22:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: