在许多脚本语言中,我们有一个这样的编程方法:
首先,有一个名为func的函数:
void func()
{
}
其次,我想在客户端调用此函数时记录一些信息,但我不想这样做 修改功能,所以我可以这样做:
void (*pfunc)(void) = func;
void func()
{
log("Someone call fund");
pfunc();
}
之后,任何拨打电话的人都会调用我的“覆盖”功能。这在许多脚本语言中都可以。我可以用C语言做同样的事情吗?以及如何编码?
我想使用这个方法在一些3party库中做一些工作,所以我必须做一些影响链接过程的事情,而不仅仅是编译过程。
答案 0 :(得分:7)
在简单的情况下,您可以用宏编码
#define func() \
do { \
log("Someone called func"); \
func(); \
} while(0)
在宏的扩展中,宏不会递归扩展。
对于更复杂的情况,您实现了一个函数和一个宏。在" .h"你要放的文件:
void func_annotated(void);
#ifdef DEBUG
# define func() func_annotated()
// or if the function takes parameters
// # define func(...) func_annotated(__VA_ARGS__)
#endif
在" .c"提交你的文件
void func_annotated(void)
{
log("Someone called func");
(func)();
}
此处额外()
arround func
可确保始终使用真实函数。
答案 1 :(得分:1)
也许您正在寻找library interposer。您可以在文件中定义自己的函数,并使用该函数而不是系统调用来调用要记录调用的程序。
例如,插入由ls
生成的一些系统调用:
$ LD_PRELOAD=/your/own/functions/file.so ls -l
它更适合于无法更改程序代码(可能因为它不可用)而调用要记录的函数的情况。
答案 2 :(得分:0)
在这种情况下,您不需要使用函数指针。你可以让函数func
获取你想要记录的任何参数。与覆盖相同的是,它不需要是函数指针(除非您打算稍后更改覆盖函数的内容)。此外,在这种情况下,它将创建一个无限循环,因为函数指针指向func
函数。此外,我甚至不确定在声明函数之前是否允许使用func
作为函数指针。
我会尝试这样的事情,这会记录一个整数,但你可以用它来记录你想要的任何东西。
void func(int value)
{
printf("%d\n", value);
anotherFunc(value);
}
其中anotherFunc()
完全是一个不同的功能。就像我之前说的那样,如果你想改变anotherFunc()
调用的函数,那么使用函数指针是有意义的,否则就不需要了。