我试图用boost :: msm实现一个简单的协议 . 当数据包到达时,它们被处理并分派到状态机(SM)以进行相应的处理 .
我的pkt类(即Pkt1)需要fsm的句柄,允许它调用 fsm->process_event(...) (当然我会将 #include "myfsm.h" 添加到pkt1.h的顶部) .
到现在为止还挺好 . 但是,如果我的状态机(比如说State1)需要通过自己发送数据包来对该数据包做出反应呢?现在我将“pkt1.h” Headers 包含在“state1.h”的顶部,这样我就可以创建Pkt1的一个实例并调用它的send()函数 .
好吧,你可能会猜到这最后的包含导致了“循环依赖”
注)在"state1.h"文件中删除 #include "pkt1.h" & on_entry(..)... Pkt1 pkt; pkt.send(); 以使其可编辑 .
问题:
1)我该如何解决这个循环依赖?
2)我认为前进的方法是为我的Pkt1类添加一个实现文件(.cpp)并将 #include "myfsm.h" 传递给该文件,从而打破循环依赖 . 但是我如何转发在头文件中声明 MyFsm ?
3)我是boost :: msm / CRTP的新手,代码让我感到困惑 . 如果没有将相应的头部包含到state1.h中,State1如何访问 MyFsm ? (也许是因为 MyFsm 派生自编译器前/后端,其头部包含在内并允许虚函数调用相应的MyFsm函数!! ??)
非常感谢您的时间和提前帮助 .
代码包括:
events.h
#ifndef EVENTS
#define EVENTS
// ----- Events
struct Event1 {};
struct Event2 {};
#endif // EVENTS
main.cpp
#include
#include "events.h"
#include "myfsm.h"
#include "pkt1.h"
int main()
{
MyFsm fsm;
fsm.start();
//fsm.process_event(Event1());
Pkt1 rcvdPkt;
rcvdPkt.dispatch(&fsm);
return 0;
}
myfsm.h
//MyFsm.h
#ifndef MYFSM
#define MYFSM
#include
#include
#include
#include
#include "state1.h"
#include "state2.h"
#include "events.h"
namespace msm = boost::msm;
namespace msmf = boost::msm::front;
namespace mpl = boost::mpl;
struct MyFsm_ : msmf::state_machine_def
{
struct State1_ : State1 {}; // use public inheritance
struct State2_ : State2 {}; // use public inheritance
// Set initial state
typedef State1_ initial_state;
// Transition table
struct transition_table:mpl::vector<
msmf::Row < State1_, Event1, State2_, msmf::none, msmf::none >
>{};
};
// Pick a back-end
typedef msm::back::state_machine MyFsm;
#endif // MYFSM
pkt1.h
#ifndef PKT1
#define PKT1
#include "myfsm.h"
#include "events.h"
class Pkt1
{
public:
Pkt1() {}
void dispatch(MyFsm *fsm){
fsm->process_event(Event1());
}
void send(){std::cout<
};
#endif // PKT1
state1.h
//State1.h
#ifndef STATE1
#define STATE1
#include
#include
#include
#include
#include "pkt1.h" //comment this line to resolve the compliation error
namespace msm = boost::msm;
namespace msmf = boost::msm::front;
namespace mpl = boost::mpl;
struct State1:msmf::state<>
{
// Entry action
template
void on_entry(Event const&, Fsm& ) const {
std::cout << "State1::on_entry()" << std::endl;
Pkt1 pkt; pkt.send();//comment this line to resolve the compliation error
}
// Exit action
template
void on_exit(Event const&, Fsm&) const {
std::cout << "State1::on_exit()" << std::endl;
}
};
#endif // STATE1
state2.h
//State2.h
#ifndef STATE2
#define STATE2
#include
#include
#include
#include
namespace msm = boost::msm;
namespace msmf = boost::msm::front;
namespace mpl = boost::mpl;
struct State2:msmf::state<>
{
// Entry action
template
void on_entry(Event const&, Fsm&) const {
std::cout << "State2::on_entry()" << std::endl;
}
// Exit action
template
void on_exit(Event const&, Fsm&) const {
std::cout << "State2::on_exit()" << std::endl;
}
};
#endif // STATE2