eDe*_*ser 5 c c++ gcc gcc-warning linker-flags
gcc 6.3 的手册页说:
--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.
Run Code Online (Sandbox Code Playgroud)
所以我创建了一个简单的例子:
#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;
}
Run Code Online (Sandbox Code Playgroud)
并编译它:
gcc main.c -Wl,--wrap=foo -o main
Run Code Online (Sandbox Code Playgroud)
这给了我一个警告:
main.c:18:21: warning: implicit declaration of function ‘__real_foo’ [-Wimplicit-function-declaration]
printf("realfoo:");__real_foo();
^~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
好在继续。现在我建议这样的输出:
foo:wrap foo
wrapfoo:wrap foo
realfoo:foo
Run Code Online (Sandbox Code Playgroud)
相反,我得到了这个:
foo:foo
wrapfoo:wrap foo
realfoo:foo
Run Code Online (Sandbox Code Playgroud)
我希望事情是清楚的。我对警告感到困惑。通常,该__real函数应由链接器链接到foo(). 此外,foo()应将调用链接到__wrap_foo. 但是输出显示,它foo()正在被执行。
如何--wrap正确使用?
正如 StoryTeller 告诉我的那样,我忽略了上面已经发布的“未定义参考”要求:
...对符号的任何未定义引用将被解析为“__wrap_symbol”。任何对“__real_symbol”的未定义引用都将被解析为符号。
要使用该--wrap选项,我重新排列了我的代码示例,如下所示:
主文件:
#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;
}
Run Code Online (Sandbox Code Playgroud)
foo.c:
#include <stdio.h>
int foo() {
printf("foo\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然后编译:
gcc main.c foo.c -Wl,--wrap=foo -o main
Run Code Online (Sandbox Code Playgroud)
运行后惊人的输出./main:
foo:wrap foo
wrapfoo:wrap foo
realfoo:foo
Run Code Online (Sandbox Code Playgroud)
诀窍是(如果我错了,请纠正我)在编译时没有定义foo()和的引用__real_foo()。即它们有**未定义的引用”,这是链接器链接requierementfoo()来__wrap_foo()和__real_foo()到foo()。