Visual Studio C链接器换行选项? [英] visual studio c linker wrap option?
问题描述
从本文使用C中的模拟对象进行单元测试:
这是通过使用
-wrap
链接器选项完成的,该选项将包装函数的名称作为参数.如果测试是使用gcc编译的,则调用可能类似于:
This is done by using the
--wrap
linker option which takes the name of the wrapped function as an argument. If the test was compiled using gcc, the invocation might look like:
$ gcc -g -Wl,-wrap = chef_cook waiter_test.c Chef.c
在Visual Studio中编译C项目时该怎么做?
How can I do this when compiling a C project in visual studio?
推荐答案
ld
中的-wrap
可以由/ALTERNATENAME
MSVC Linker中的选项.
The --wrap
in ld
can be emulated by the /ALTERNATENAME
option in MSVC Linker.
我们从两个编译单元开始,例如从 foo.c
编译的 foo.o
,其外部函数在 foo.h
中声明,以及 main.c
中的 main.o
.(如果 foo
已被编译为库,则不会有太大变化.)
We start from two compilation units, say foo.o
compiled from foo.c
, whose external functions are declared in foo.h
, and main.o
from main.c
.
(If foo
has been compiled as a library, things won't change much.)
// foo.h
int foo();
// foo.c
int foo() {
return 0;
}
// main.c
#include <stdio.h>
#include "foo.h"
int main() {
int x = foo();
printf("%s\n", x ? "wrapped" : "original");
}
int foo()
的返回值为0,因此上面的代码段将输出原始".
The return value of int foo()
is 0, so the snippet of code above will output "original".
现在,我们用别名覆盖实际的实现: main.c
中的 #include"foo.h"
被替换为
Now we override the actual implementation by an alias: The #include "foo.h"
in main.c
is replaced by
#define foo real_foo
#include "foo.h"
#undef foo
#pragma comment(linker, "/alternatename:real_foo=foo")
让我解释一下这里发生的事情:
Let me explain what happens here:
- 通过
#define foo real_foo
,将foo.h
中的函数声明修改为int real_foo()
. - 但是,
foo.o
中的符号仍以int foo()
命名,而不是别名int real_foo()
.这就是为什么我们需要/alternatename
链接器开关. -
"/alternatename:real_foo = foo"
告诉链接器,如果找不到名为real_foo
的符号,请再次尝试foo 在引发错误之前. - 显然,没有定义
int real_foo()
.MSVC链接器将搜索int foo()
,并在每次出现int real_foo()
时链接它.
- by
#define foo real_foo
, the function declaration infoo.h
is modified asint real_foo()
. - However, the symbol in
foo.o
is still named afterint foo()
, instead of the aliasint real_foo()
. That's why we need the/alternatename
linker switch. "/alternatename:real_foo=foo"
tells the linker that, if you cannot find the symbol calledreal_foo
, tryfoo
again before throwing an error.- Apparently there is no definition of
int real_foo()
. MSVC Linker will search forint foo()
and link it instead at each occurrence ofint real_foo()
.
由于先前的实现已被别名,现在我们通过一个宏将 int foo()
重定向到我们的新实现:
As the previous implementation has been aliased, now we redirect int foo()
to our new implementation by a macro:
int wrap_foo() {
return real_foo() + 1;
}
#define foo wrap_foo
我们在这里完成了.最后, main.cpp
看起来像:
And we are done here. At last the main.cpp
looks like:
#include <stdio.h>
#define foo real_foo
#include "foo.h"
#undef foo
#pragma comment(linker, "/alternatename:real_foo=foo")
int wrap_foo() {
return real_foo() + 1;
}
#define foo wrap_foo
int main() {
int x = foo();
printf("%s\n", x ? "wrapped" : "original");
}
内置于MSVC中,它将输出包装".
Built in MSVC, it will output "wrapped".
这篇关于Visual Studio C链接器换行选项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!