我希望能够在一个大系统中包含任何函数,该函数将在包装函数之前和之后插入一些语句。这些添加的语句将用于特殊目的,例如计时函数执行或打印调试消息或任何类型的消息。
包装器不必绝对只有一个函数(或宏),但如果需要多个函数,则应将它们保持在最小值。
为了更好地解释我想在这里做的是一个例子:
现有代码:
void my_big_function(void) {
int data1;
int data2;
int ret1;
fun1();
ret1 = fun2();
anotherfun3(data1);
myfun4();
awesomefun5(data2);
}
需要将其更改为: void run_and_time
run_and_time(void* fun_p, void* retval, ... )
{
// statements before calling the function (e.g. get current time)
// call the function and give it the parameters it needs.
// statements After calling the function (e.g. get new time and subtract start time from it)
}
void my_big_function(void) {
run_and_time(&fun1, NULL);
run_and_time(&fun2, &ret1);
run_and_time(&anotherfun3, NULL, data1);
run_and_time(&myfun4, NULL);
run_and_time(&awesomefun5, NULL, data2);
}
这需要在标准C中完成。
更新: 在某些环境中,您无法运行配置文件以及时调试函数调用。例如,考虑嵌入式系统的Linux内核中的启动过程。在这种情况下,工具链可能无法保持在较高且有用的水平。
要提出一些建议,我们可以查看Linux内核中的start_kernel函数。在该函数中,对void f(void)
类型的函数进行了一系列调用。对于这种类型的功能来说很容易。以下是可以做的事情的抽象示例:
#include <stdio.h>
#include <stdlib.h>
#ifdef MY_DEFINITION
#include <sys/time.h>
#define time_func_call(x, y) do { \
struct timeval tv1, tv2; \
gettimeofday(&tv1, NULL); \
x(); \
gettimeofday(&tv2, NULL); \
printf ("%s took %lu micro seconds to finish\n", y, (tv2.tv_usec - tv1.tv_usec) + \
(tv2.tv_sec - tv1.tv_sec) * 1000000); \
\
} while (0)
#else
#define time_func_call(x, y) do { \
x();\
} while (0)
#endif
void good_function(void){
printf("Inside good_function\n");
return;
}
int main(int argc, char** argv) {
time_func_call(good_function, "good_function");
return (EXIT_SUCCESS);
}
这是一个测试运行:
$ gcc -o ./test ./main.c
$ ./test
Inside good_function
$ gcc -o ./test -DMY_DEFINITION ./main.c
$ ./test
Inside good_function
good_function took 51 micro seconds to finish
现在,这适用于特定类型的功能。但我们可以扩展它以与其他签名一起使用吗?