visual studio c компоновщиком?

Из этой статьи Модульное тестирование с фиктивными объектами в C

Это делается с помощью опции компоновщика --wrap, которая принимает имя обернутой функции в качестве аргумента. Если тест был скомпилирован с использованием gcc, вызов может выглядеть следующим образом:

$ gcc -g -Wl,--wrap=chef_cook waiter_test.c chef.c

Как я могу сделать это при компиляции AC проекта в Visual Studio?

1 ответ

В --wrap в ld может быть эмулирован /ALTERNATENAME вариант в компоновщике MSVC.

Мы начинаем с двух единиц компиляции, скажем, скомпилированных из foo.c, чьи внешние функции объявлены в, и main.oиз . (Если он был скомпилирован как библиотека, многое не изменится.)

      // 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");
}

Возвращаемое значение равно 0, поэтому приведенный выше фрагмент кода выведет «оригинал».

Теперь мы заменяем фактическую реализацию псевдонимом: #include "foo.h" в main.c заменяется на

      #define foo real_foo
#include "foo.h"
#undef foo
#pragma comment(linker, "/alternatename:real_foo=foo")

Позвольте мне объяснить, что здесь происходит:

  1. к #define foo real_foo, объявление функции в foo.h модифицируется как.
  2. Однако символ в foo.oпо-прежнему назван в честь, а не псевдонимом. Вот почему нам нужен /alternatename переключатель компоновщика.
  3. "/alternatename:real_foo=foo" сообщает компоновщику, что если вы не можете найти символ с именем real_foo, пытаться foo еще раз, прежде чем выбросить ошибку.
  4. Видимо нет определения. Компоновщик MSVC будет искать и связывать его вместо этого при каждом появлении 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, он будет выводить «завернутый».

Другие вопросы по тегам