Visual Studio C链接器换行选项? [英] visual studio c linker wrap option?

查看:96
本文介绍了Visual Studio C链接器换行选项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从本文使用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:

  1. 通过 #define foo real_foo ,将 foo.h 中的函数声明修改为 int real_foo().
  2. 但是, foo.o 中的符号仍以 int foo()命名,而不是别名 int real_foo().这就是为什么我们需要/alternatename 链接器开关.
  3. "/alternatename:real_foo = foo" 告诉链接器,如果找不到名为 real_foo 的符号,请再次尝试 foo 在引发错误之前.
  4. 显然,没有定义 int real_foo().MSVC链接器将搜索 int foo(),并在每次出现 int real_foo()时链接它.
  1. by #define foo real_foo, the function declaration in foo.h is modified as int real_foo().
  2. However, the symbol in foo.o is still named after int foo(), instead of the alias int real_foo(). That's why we need the /alternatename linker switch.
  3. "/alternatename:real_foo=foo" tells the linker that, if you cannot find the symbol called real_foo, try foo again before throwing an error.
  4. Apparently there is no definition of int real_foo(). MSVC Linker will search for int foo() and link it instead at each occurrence of int 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆