1

在许多脚本语言中,我们都有这样的编程方法:

首先,有一个名为 func 的函数:

void func()
{
}

其次,我想在客户端调用此函数时记录一些信息,但我不想修改函数,所以我可以执行以下操作:

void (*pfunc)(void) = func;
void func()
{
    log("Someone call fund");
    pfunc();
}

之后,任何调用基金的人都会调用我的“覆盖”函数。这在许多脚本语言中都可以。我可以用 C 语言做同样的事情吗?以及如何编码?

我想用这种方法在一些3party库中做一些工作,所以我必须做一些影响链接过程的事情,而不仅仅是编译过程。

4

3 回答 3

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)();
}

在这里,额外的()arroundfunc确保它始终使用真正的功能。

于 2012-08-03T14:16:06.040 回答
1

也许您正在寻找库插入器。您可以在文件中定义自己的函数,并使用该函数而不是系统调用调用要记录调用的程序。

例如,插入一些系统调用ls

$ LD_PRELOAD=/your/own/functions/file.so ls -l

它更适合您无法更改调用要记录的函数的程序代码(可能是因为它不可用)的情况。

于 2012-08-03T14:35:31.373 回答
0

在这种情况下,您不需要使用函数指针。您可以让函数func为您想要记录的任何内容获取参数。与覆盖相同,它不需要是函数指针(除非您计划稍后更改覆盖函数)。此外,在这种情况下,它将创建一个无限循环,因为函数指针指向该func函数。此外,我什至不确定是否允许func在声明函数之前将其用作函数指针。

我会尝试这样的事情,这会记录一个整数,但你可以用它来记录你想要的任何东西。

void func(int value)
{
    printf("%d\n", value);
    anotherFunc(value);
}

whereanotherFunc()是完全不同的功能。就像我之前说的,如果你想改变被调用的函数,anotherFunc()那么使用函数指针是有意义的,否则就不需要了。

于 2012-08-03T14:21:04.807 回答