2017-09-27 55 views
3

GCC 6.3的手册页说:如何正确使用`--wrap`选项来包装函数?

--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. 
      ... 
      If you link other code with this file using --wrap malloc, then all 
      calls to "malloc" will call the function "__wrap_malloc" instead. 
      The call to "__real_malloc" in "__wrap_malloc" will call the real 
      "malloc" function. 

所以我创建了一个简单的例子:

#include <stdio.h> 

int foo() { 
    printf("foo\n"); 
    return 0; 
} 

int __wrap_foo() { 
    printf("wrap foo\n"); 
    return 0; 
} 

int main() { 
    printf("foo:");foo(); 
    printf("wrapfoo:");__wrap_foo(); 
    printf("realfoo:");__real_foo(); 
    return 0; 
} 

并编译它:

gcc main.c -Wl,--wrap=foo -o main 

这给了我一个警告:

main.c:18:21: warning: implicit declaration of function ‘__real_foo’ [-Wimplicit-function-declaration] 
    printf("realfoo:");__real_foo(); 
        ^~~~~~~~~~ 

好吧。现在,我建议像这样的输出:

foo:wrap foo 
wrapfoo:wrap foo 
realfoo:foo 

相反,我得到这样的:

foo:foo 
wrapfoo:wrap foo 
realfoo:foo 

我希望事情是清楚的。我对这个警告感到困惑。通常,__real函数应该由链接器链接到foo()。此外,致电foo()应与__wrap_foo挂钩。但输出显示,foo()正在执行。

如何正确使用--wrap

+4

它做的工作。但是,因为你有一个翻译单元,和'foo'存在,通话到'foo'不是一个**未定义的引用**到'foo'。 – StoryTeller

+0

嗯,我不明白。上面的例子的输出对我来说似乎是错误的。'foo()'应该输出''wrap foo' ! 我究竟做错了什么? – eDeviser

+2

您忽略了“未定义参考”**要求**。 – StoryTeller

回答

2

至于讲故事的人告诉我,我忽略我上面已经贴了“未定义的引用”的要求:

...任何未定义参考到符号将被解析为“__wrap_symbol”。任何未定义的参考到“__real_symbol”将被解析为符号。

要使用--wrap选项我重新安排我的代码,例如这样的:

的main.c:

#include <stdio.h> 
extern int foo(); 
extern int __real_foo(); 

int __wrap_foo() { 
    printf("wrap foo\n"); 
    return 0; 
} 

int main() { 
    printf("foo:");foo(); 
    printf("wrapfoo:");__wrap_foo(); 
    printf("realfoo:");__real_foo(); 
    return 0; 
} 

foo.c的:

#include <stdio.h> 
int foo() { 
    printf("foo\n"); 
    return 0; 
} 

然后编译:

gcc main.c foo.c -Wl,--wrap=foo -o main 

运行./main后,惊人的输出:

foo:wrap foo 
wrapfoo:wrap foo 
realfoo:foo 

诀窍是(纠正我,如果我错了)认为foo()__real_foo()引用不会在编译时定义。即它们有**未定义的引用,”这是为requierement链接链接到foo()__wrap_foo()__real_foo()foo()