如何在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; } 
Interesting Posts