c语言指针指向已有函数,确定指针在C中指向哪个函数?

确定指针在C中指向哪个函数?

我有一个指向函数的指针,假定有任何签名。我有5个具有相同签名的不同功能。

在运行时,将其中一个分配给指针,然后调用该函数。

在这些函数中不插入任何打印语句,如何知道指针当前指向的函数名?

Sumit asked 2020-01-08T15:11:51Z

9个解决方案

65 votes

您将必须检查指针所指向的5个函数中的哪个:

if (func_ptr == my_function1) {

puts("func_ptr points to my_function1");

} else if (func_ptr == my_function2) {

puts("func_ptr points to my_function2");

} else if (func_ptr == my_function3) {

puts("func_ptr points to my_function3");

} ...

如果这是您需要的常见模式,请使用结构表代替函数指针:

typedef void (*my_func)(int);

struct Function {

my_func func;

const char *func_name;

};

#define FUNC_ENTRY(function) {function, #function}

const Function func_table[] = {

FUNC_ENTRY(function1),

FUNC_ENTRY(function2),

FUNC_ENTRY(function3),

FUNC_ENTRY(function4),

FUNC_ENTRY(function5)

}

struct Function *func = &func_table[3]; //instead of func_ptr = function4;

printf("Calling function %s\n", func->func_name);

func ->func(44); //instead of func_ptr(44);

nos answered 2020-01-08T15:12:06Z

27 votes

通常,在C语言中,程序员无法使用这些功能。

通过使用调试符号等可能有特定于系统的方法,但是您可能不希望依赖这些方法的存在来使程序正常运行。

但是,您当然可以将指针的值与另一个值进行比较,例如

if (ptr_to_function == some_function)

printf("Function pointer now points to some_function!\n");

janneb answered 2020-01-08T15:12:35Z

16 votes

函数名称在运行时将不可用。

C不是反射性语言。

维护以其名称为键的函数指针表,或者提供一种调用返回该名称的函数的模式。

Bathsheba answered 2020-01-08T15:13:04Z

15 votes

调试器可以告诉您(即函数的名称,给出其地址)。

未剥离的ELF可执行文件的符号表也可能会有所帮助。 参见nm(1),objdump(1),readelf(1)

另一种Linux GNU / libc特定方法可能是在运行时使用dladdr(3)函数。 假设您的程序被很好地动态链接(例如使用dlopen),则它可以找到符号名称和共享对象路径(给定全局函数的地址)。

当然,如果给定签名只有五个功能,则可以将您的地址(与它们的五个地址)进行比较。

请注意,某些函数没有任何((全局可见))名称,例如dlopen函数。

某些功能可能是dlopen-ed和dlsym-ed(例如,在插件内部)。 或者它们的代码在运行时由某些JIT-ing框架合成(libjit、gccjit、LLVM、asmjit)。 而且优化的编译器可以(并且确实可以!)内联函数,克隆它们,尾部调用它们,等等...因此,您的问题通常可能没有任何意义...

另请参阅backtrace(3)和GCC中Ian Taylor的libbacktrace。

但总的来说,您的追求是不可能的。 如果您确实需要可靠的方式提供此类反射性信息,请自己进行管理(以Pitrat的CAIA系统为例,或者以某种方式查看我的MELT系统),也许可以在构建过程中生成一些代码即可。

Basile Starynkevitch answered 2020-01-08T15:13:56Z

13 votes

要知道函数指针指向的位置,您必须对程序进行跟踪。 最常见的是声明一个函数指针数组,并使用一个int变量作为该数组的索引。

话虽如此,如今也可以通过使用__func__标识符在运行时告诉当前正在执行哪个功能:

#include

typedef const char* func_t (void);

const char* foo (void)

{

// do foo stuff

return __func__;

}

const char* bar (void)

{

// do bar stuff

return __func__;

}

int main (void)

{

func_t* fptr;

fptr = foo;

printf("%s executed\n", fptr());

fptr = bar;

printf("%s executed\n", fptr());

return 0;

}

输出:

foo executed

bar executed

Lundin answered 2020-01-08T15:14:26Z

10 votes

完全没有-函数的符号名称在编译后消失。 与反射语言不同,C并不知道程序员如何命名其语法元素。 特别是,编译后没有按名称进行“函数查找”。

当然,您可以拥有一个功能指针的“数据库”(例如数组),您可以将其与当前指针进行比较。

Marcus Müller answered 2020-01-08T15:14:51Z

8 votes

这是非常糟糕且不可移植的,但假设:

您使用的是Linux或类似的基于ELF的系统。

您正在使用动态链接。

该函数在共享库中,或者您在链接时使用了dladdr。

也许您不应该做出许多其他假设...

您可以通过将函数的地址传递给非标准的dladdr函数来获得函数的名称。

R.. answered 2020-01-08T15:15:34Z

3 votes

设置链接器以输出MAP文件。

暂停程序

检查指针中包含的地址。

在MAP文件中查找地址,以找出要指向的功能。

Mark Ch answered 2020-01-08T15:16:07Z

0 votes

指向C函数的指针是一个地址,就像任何指针一样。 您可以从调试器获取值。 您可以将指针转换为具有足够位数的任意整数类型,以完整地表达它并进行打印。 任何可以使用指针的编译单元,即在范围内具有函数名称,都可以打印指针值或将它们与运行时变量进行比较,而无需触及函数内部的任何内容。

Bill IV answered 2020-01-08T15:16:27Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值