如何在C中包装现有函数
我试图包装现有的function。
下面的代码是完美的工作。
#include int __real_main(); int __wrap_main() { printf("Wrapped main\n"); return __real_main(); } int main() { printf("main\n"); return 0; }
命令:
gcc main.c -Wl,-wrap,main
输出:
Wrapped main main
所以我用temp改变了主要function。 我的目标是包装temp()函数。
以下是代码
temp.c
#include int temp(); int __real_temp(); int __wrap_temp() { printf("Wrapped temp\n"); return __real_temp(); } int temp() { printf("temp\n"); return 0; } int main() { temp(); return 0; }
命令:
gcc temp.c -Wl,-wrap,temp
输出:
temp
包裹的温度不打印。 请指导我包装function临时。
ld的联机帮助页说:
--wrap=symbol Use a wrapper function for symbol. Any undefined reference to symbol will be resolved to "__wrap_symbol". Any undefined reference to "__real_symbol" will be resolved to symbol.
这里的关键字是未定义的。
如果将定义temp
放在与使用它的代码相同的转换单元中,则在使用它的代码中不会定义它。
您需要拆分代码定义和使用它的代码:
#!/bin/sh cat > user.c <<'EOF' #include int temp(void); int __real_temp(void); int __wrap_temp() { printf("Wrapped temp\n"); return __real_temp(); } int main() { temp(); return 0; } EOF cat > temp.c <<'EOF' #include int temp() { printf("temp\n"); return 0; } EOF gcc user.c -Wl,-wrap,temp temp.c # OK ./a.out
将构建拆分为两个单独的编译可能会使它更清晰:
$ gcc -c user.c $ gcc -c temp.c $ nm user.o temp.o temp.o: U puts 0000000000000000 T temp user.o: 0000000000000015 T main U puts U __real_temp U temp 0000000000000000 T __wrap_temp
现在,因为在user.c
未定义temp
,链接器可以对其执行__real_
/ __wrap_
魔术。
$ gcc user.o temp.o -Wl,-wrap=temp $ ./a.out Wrapped temp temp
如果您可以从要调用它的函数中拆分要覆盖的函数,那么PSCocik提出的答案效果很好。 但是,如果要将被调用者和调用者保持在同一源文件中,则--wrap
选项将不起作用。
相反,您可以在执行被调用者之前使用__attribute__((weak))
,以便让某人重新实现它而不会让GCC大肆宣传多个定义。
例如,假设您要在以下hello.c代码单元中模拟world
函数。 您可以添加属性以便能够覆盖它。
#include "hello.h" #include __attribute__((weak)) void world(void) { printf("world from lib\n"); } void hello(void) { printf("hello\n"); world(); }
然后,您可以在另一个单元文件中覆盖它。 对unit testing/模拟非常有用:
#include #include "hello.h" /* overrides */ void world(void) { printf("world from main.c"\n); } void main(void) { hello(); return 0; }