简体   繁体   English

面向对象的C有限状态机

[英]Object-Oriented C Finite State Machine

I have a software state machine that works using via an event driven function calls. 我有一个软件状态机,通过事件驱动的函数调用使用。 Namely, I have a state machine handle to a struct that contains a function pointer representing the current state: 也就是说,我有一个结构的状态机句柄,它包含一个表示当前状态的函数指针:

typedef struct pHandle_t pHandle_t;
typedef void(*pState_f)(pHandle_t *pHandle, pEvent_t pEvent);
struct pHandle_t
{
    pState_f curState;
    void *contextPtr;       // Is this needed?
};

Each state is then represented by a function that takes a handle to itself and an event as input: 然后,每个状态由一个函数表示,该函数将自身的句柄和事件作为输入:

static void SM_Init(pHandle_t *pHandle, pEvent_t pEvent);

Within each function there is a switch/case on the pEvent that usually produces some action as well as changing the curState function pointer to change to the function representing the state. 在每个函数中,pEvent上有一个开关/ case,通常会产生一些动作,并且更改curState函数指针以更改为表示状态的函数。 All of this code works very well while using global variables to determine when certain state changes are done. 所有这些代码都可以很好地工作,同时使用全局变量来确定何时完成某些状态更改。 (This type of approach obviously would not work well with function instantiated variables to try and know when to stop). (这种方法显然不适用于函数实例化变量以尝试知道何时停止)。

However, in the interest of reducing global variables and functions, I would like to implement a more object oriented approach, so that my globals and instruction memory go away once the state machine has reached a complete state. 但是,为了减少全局变量和函数,我想实现一种更面向对象的方法,这样一旦状态机达到完全状态,我的全局变量和指令存储器就会消失。 I know there are several examples of how to make code appear object oriented in regular C, but there is one wrench in the gears here: External modules need to be able to send events to this state machine without having a pointer to the state machine handle. 我知道有几个例子说明如何使代码在常规C中出现面向对象,但这里有一个扳手:外部模块需要能够向这个状态机发送事件而不需要指向状态机句柄的指针。 How can I do this without requiring the overall state machine object be declared as a global (which really defeats the original intent of trying to free all that space once I was done with it)? 如何在不要求将整个状态机对象声明为全局的情况下执行此操作(这实际上违背了在完成后尝试释放所有空间的原始意图)?

I apologize in advance if some of this wording is confusing. 如果这些措辞有些令人困惑,我会提前道歉。 I believe this is a very useful topic so I will reword as requested, but please comment before downvoting me... Also before anyone asks, the existing code base is all C and suggesting C++ falls on deaf ears, despite all my efforts. 我相信这是一个非常有用的话题,所以我会按照要求进行改写,但请在向我发表评论之前发表评论......在任何人要求之前,现有的代码库都是C,并且尽管我付出了很多努力,但仍然建议C ++充耳不闻。

This is probably a terrible idea, but as such, it may help to convince your peers to let you store one little, measly pointer where you need it. 这可能是一个糟糕的主意,但同样地,它可能有助于说服你的同伴让你在你需要的地方存储一个小的,可怜的指针。

If all you have to identify instances of state machine objects is the callback-function pointer, then to have multiple machines running, you'll need duplicates of all the functions so that different pointers can be functionally-identical, but compare differently when cast to char * . 如果您必须识别状态机对象的实例是回调函数指针,那么要让多台机器运行,您需要复制所有函数,以便不同的指针在功能上可以相同,但在转换为char *

So for two machines, you'll need roughly double the code size. 因此,对于两台机器,您需要大约两倍的代码大小。 Three machines: triple. 三台机器:三合一。 Etc. 等等。

<shudder> <颤动>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM