在MSVC(Visual Studio)中模拟C函数

我正在阅读有关模拟C函数(例如CMockCMocka)的几篇文章,但是我不确定在此过程中如何将实际函数替换为模拟函数。例如,CMocka依赖于使用GNU编译器的自动包装,该编译器支持将参数--wrap附加__wrap到函数调用之后的参数,或者弱符号允许您覆盖所需的任何符号。

但是对于几乎所有其他框架,您如何在Visual Studio中执行此操作?

例如,CMock的示例与此相似(此处已简化很多):

// myfunc.c
#include <parsestuff.h>

// this is the function we would like to test
int MyFunc(char* Command)
{
    // this is the call to the function we will mock
    return ParseStuff(Command);
}

还有一个实际的实现,其中包含链接器应在实际应用程序中找到的实际功能:

// parsestuff.c

int ParseStuff(char* cmd)
{
    // do some actual work
    return 42;
}

现在,在测试过程中,Ruby脚本会创建模拟函数,例如:

// MockParseStuff.c (auto created by cmock)

int ParseStuff(char* Cmd);
void ParseStuff_ExpectAndReturn(char* Cmd, int toReturn);
  1. 但是,如果VS项目已经包括在内parsestuff.c,那么来自的调用怎么可能myfunc.c终止于MockParseStuff.c

  2. 这是否意味着我不能parsestuff.c包含在单元测试项目中?但是,如果是这样的话,那么它也不可能嘲笑,例如,MyFuncmyfunc.c在任何测试,因为我已经有包括文件它以测试它?

(更新)我也知道我可以包括.c文件而不是.h文件,然后做一些预处理程序来替换原始调用,例如:

// replace ParseStuff with ParseStuff_wrap
#define ParseStuff ParseStuff_wrap
// include the source instead of the header
#include <myfunc.c>
#undef ParseStuff

int ParseStuff_wrap(char* cmd) 
{
    // this will get called from MyFunc,
    // which is now statically included
}

但这似乎有很多问题,而且我什至没有看到它在任何地方提及。

阿塔里

这是河马的一个简单而简短的解决方案:

我用创建了一个空的Win32控制台应用程序

  • main.cpp
  • myfunc.c + myfunc.h
  • parsestuff.c,parsestuff.h

并在您的示例中添加了代码。

借助河马,您可以模拟每个C函数。这是我的main.cpp的样子:

#include "stdafx.h"
#include "myfunc.h"
#include "hippomocks.h"


extern "C" int ParseStuff(char* cmd);

int _tmain(int argc, _TCHAR* argv[])
{
    MockRepository mocks;

    mocks.ExpectCallFunc(ParseStuff).Return(4711);

    char buf[10] = "";

    int result = MyFunc(buf);

    return result; //assert result is 4711
}

HippoMocks是一个免费,简单且功能强大的单头框架,可以在GitHub上下载。

希望我已经获得了赏金:)

更新,它是如何工作的:

  1. HippoMocks获取指向ParseStuff的func指针
  2. HippoMocks使用相同的签名和自己的实现为模板函数构建替换的func指针。
  3. Hippomocks从内存中的函数调用序言中修补jmp操作码,使其指向替换后的函数。
  4. 调用后或在析构函数中释放替换和内存补丁。

这是我的机器上的样子:

@ILT+3080(_ParseStuff):
00D21C0D  jmp HippoMocks::mockFuncs<char,int>::static_expectation1<0,char *> (0D21DB1h)  

如果在内存窗口中看到内存地址00D21C0D(可能与运行时有所不同),则会看到在调用ExpectCallFunc之后,它会被修补。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在Visual Studio MSVC中erf的精度是多少?

哪个Visual Studio组件包含MSVC Hostx文件?

MSVC (Visual C++) 是否有 -Weffc++ 等效项?

C ++ / Visual Studio中的构造函数

如何在MSVC ++(Microsoft Visual Studio)中解决与“宏重载”相关的可变参数宏相关问题?

尽管已安装Microsoft Visual Studio 2012,但在eclipse中找不到MSVC工具链

在Visual Studio MSVC 14.0断言下使用Boost程序选项失败

Visual Studio 2012中的模拟参考

Cmake:分别为 MSVC (Visual C++) 设置 C 和 C++ 代码的警告级别

在Visual Studio C#中的PictureBox中填写函数吗?

从Visual Studio中的asm调用C标准库函数

如何使用 Visual Studio 单元测试框架或 NUnit 框架在 C# 中模拟对象?

Visual Studio中的C ++

在Visual Studio中模拟GCC的__builtin_unreachable?

如何在Visual Studio测试中模拟数据存储库?

在Python / PIP中安装REBOUND时出错:... Microsoft Visual Studio \\ MSVC \\ 14.28.29333 \\ bin \\ HostX86 \\ x64 \\ cl.exe'失败,退出代码为2

错误:命令'C:\\ Visual Studio \\ 2017 \\ Community \\ VC \\ Tools \\ MSVC \\ 14.14.26428 \\ bin \\ HostX86 \\ x64 \\ cl.exe'失败,退出状态为2

在Visual Studio中缺少析构函数?

Visual Studio 中的 sqrtf 函数替代

Visual Studio C 编程函数定义

在C中包装C ++成员函数-Visual Studio 2013模板出现问题

应用程式无法在Visual Studio 2015的Android Visual Studio模拟器中执行

Visual Studio 2013中适用于Android的Visual Studio模拟器

Visual c ++中的函数重载

Visual Studio中的C编程

C,Visual Studio中的Malloc

哪些编译器选项用于在Visual Studio中编译C ++ STL类/函数?

在Visual Studio中的C#通用类/方法上设置函数断点?

您可以在Visual Studio Code for C ++中重命名函数吗?