Sum*_*mit 53 c function-pointers
我有一个指向函数的指针,假设有任何签名.我有5个不同的功能和相同的签名.
在运行时,其中一个被分配给指针,并调用该函数.
如果不在这些函数中插入任何print语句,我怎样才能知道指针当前指向的函数名称?
nos*_*nos 65
您必须检查指针指向的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");
} ...
Run Code Online (Sandbox Code Playgroud)
如果这是您需要的常见模式,则使用结构表而不是函数指针:
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);
Run Code Online (Sandbox Code Playgroud)
jan*_*neb 27
通常,在C中,程序员无法使用这些东西.
通过使用调试符号等可能有系统特定的方法到达那里,但您可能不希望依赖于这些方法的存在以使程序正常运行.
但是,您当然可以将指针的值与另一个值进行比较,例如
if (ptr_to_function == some_function)
printf("Function pointer now points to some_function!\n");
Run Code Online (Sandbox Code Playgroud)
Bas*_*tch 15
调试器可以告诉你(即函数的名称,给定其地址).
未提取的ELF可执行文件的符号表也可以提供帮助.见nm(1),objdump(1),readelf(1)
另一种Linux GNU/libc特定的方法可能是在运行时使用dladdr(3)函数.假设您的程序很好地动态链接(例如-rdynamic),它可以找到符号名称和共享对象路径给定一些地址(全局命名的函数).
当然,如果您只有给定签名的五个函数,则可以比较您的地址(到它们的五个地址).
请注意,某些函数没有任何((全局可见)名称,例如static函数.
并且可以对一些函数进行dlopen-ed和dlsym-ed(例如在插件内部).或者他们的代码被一些JIT-ING框架(在运行时synthetized libjit,gccjit,LLVM,asmjit).并且优化编译器可以(并且确实!)内联函数,克隆它们,尾随它们等等....所以你的问题一般没有任何意义......
另请参阅回溯(3)和Ian Taylor 在GCC中的libbacktrace.
但总的来说,你的追求是不可能的.如果您确实需要可靠的反馈信息,请自行管理(以Pitrat的CAIA系统为例,或以某种方式查看我的MELT系统),或许可以在构建过程中生成一些代码.
Lun*_*din 13
要知道函数指针指向的位置,您必须跟踪程序.最常见的是声明一个函数指针数组,并使用int变量作为此数组的索引.
话虽如此,现在也可以通过使用__func__标识符在运行时告诉当前执行哪个函数:
#include <stdio.h>
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;
}
Run Code Online (Sandbox Code Playgroud)
输出:
foo executed
bar executed
Run Code Online (Sandbox Code Playgroud)
Mar*_*ler 10
完全没有 - 编译后函数的符号名称消失了.与反射语言不同,C不知道程序员如何命名其语法元素; 特别是,编译后没有名称的"函数查找".
您当然可以拥有一个函数指针的"数据库"(例如数组),您可以将当前指针与之进行比较.