gpt4 book ai didi

c - Visual Studio C 链接器包装选项?

转载 作者:行者123 更新时间:2023-12-03 20:20:00 26 4
gpt4 key购买 nike

来自这篇文章 Unit testing with mock objects in C :

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 项目时如何执行此操作?

最佳答案

--wrapld可以通过 /ALTERNATENAME 模拟MSVC 链接器中的选项。
我们从两个编译单元开始,比如 foo.o编译自 foo.c ,其外部函数在 foo.h 中声明, 和 main.o来自 main.c .
(如果 foo 已经编译为一个库,事情不会有太大变化。)

// 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,所以上面的代码片段将输出“原始”。
现在我们用别名覆盖实际的实现: #include "foo.h"main.c被替换为
#define foo real_foo
#include "foo.h"
#undef foo
#pragma comment(linker, "/alternatename:real_foo=foo")
让我解释一下这里发生了什么:
  • 来自 #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() 时链接它.

  • 由于之前的实现已经别名化,现在我们重定向 int foo()通过宏来实现我们的新实现:
    int wrap_foo() {
    return real_foo() + 1;
    }
    #define foo wrap_foo
    我们已经完成了。最后 main.cpp好像:
    #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,它将输出“wrapped”。

    关于c - Visual Studio C 链接器包装选项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33790425/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com