如何在unit testingC时重置状态机

我有一个用于TI处理器的嵌入式C,需要进行unit testing。
对于目标编译,使用IAR,但我使用MinGW GCC在Win7机器上运行测试。

在C代码中,有些函数包含有时需要在测试之间重置的状态机。 这些状态机通常将其状态变量保持在本地静态,即使不是不可能,也很难完成该任务。

我不是很精通C ++类,但我有一个关于将C函数“导入”包装C ++类的想法作为成员函数,可以在需要重置时创建一个新对象。 下面的代码不起作用,但它说明了我的想法。

在main.cpp中:

#include "statemachine.h" using namespace std; class stateMachineWrapper { public: extern void stateMachine(void); }; int main() { stateMachineWrapper myObject; myObject.stateMachine(); myObject.stateMachine(); stateMachineWrapper myNewObject; myNewObject.stateMachine(); myNewObject.stateMachine(); return 0; } 

在statemachine.h中:

  void stateMachine(void); 

在statemachine.c中:

  #include  void stateMachine(void) { static int myState = 0; switch(myState) { case 0: { printf("Init State"); myState = 1; break; } case 1: { printf("Second state"); break; } default: { printf("Default"); break; } } } 

不鼓励改变statemachine.c / .h,因为它可以被认为是“遗产”。
任何其他解决方案当然也是受欢迎的!

包装无济于事。 C ++代码无法到达用C编写的状态机内部的内部static变量。

一种解决方案是使用C部件的动态代码加载,这将使早期初始化代码和清除static变量。

您还可以将测试拆分为多个可执行文件,这些可执行文件具有相同的效果,但开销可能更大(=测试运行速度更慢)。

@unwind发送给我看动态代码加载!
阅读这些: 从DLL动态加载函数 , http://www.transmissionzero.co.uk/computing/building-dlls-with-mingw/给了我足够的能力来编写以下解决方案。

在statemachine.h中:

  void stateMachine(void); 

在statemachine.c中:

  #include  void stateMachine(void) { static int myState = 0; switch(myState) { case 0: { printf("Init State"); myState = 1; break; } case 1: { printf("Second state"); break; } default: { printf("Default"); break; } } } 

在statemachinelib.c中:

  #include "statemachine.h" __declspec(dllexport) void __cdecl statemachineWrap() { stateMachine(); } 

在main.c中:

  #include  #include  #include  typedef int (__stdcall *f_funci)(); int main(int argc, char **argv) { HINSTANCE hGetProcIDDLL = LoadLibrary("statemachinelib.dll"); f_funci funci = (f_funci)GetProcAddress(hGetProcIDDLL, "statemachineWrap"); funci(); funci(); funci(); FreeLibrary(hGetProcIDDLL); //Windows detects that no one is using this library anymore and unloads it from memory, giving the new LoadLibrary a fresh instance hGetProcIDDLL = LoadLibrary("statemachinelib.dll"); funci = (f_funci)GetProcAddress(hGetProcIDDLL, "statemachineWrap"); funci(); funci(); funci(); return 0; } 

在这段代码中,我省略了很多安全语句,例如检查是否可以加载DLL,是否找到函数,是否需要dllexport或dllimport等等,只是为了更容易理解正在发生的事情。 如果您要在任何实际项目中实现这一点,您至少应该阅读我上面提到的两种资源。

使用MinGW编译DLL:

 >gcc -c statemachine.c statemachinelib.c >gcc -o statemachinelib.dll -s -shared statemachinelib.o statemachine.o -Wl,--subsystem,windows 

编译可执行文件,也是MinGW:

 >gcc -o main.exe main.c 

执行收益率:

 >main.exe Init State Second state Second state Init State Second state Second state 

我会在这里留下几天,如果没有人反对,我会将此标记为我接受的答案!

编辑:我已经详细阐述了一点,这里有另一个(已解决的)问题,只需稍微调整导出一个函数,通过DLL强制转换为指针