Boost.SML - 违反内存 protection/Segmentation 故障
Boost.SML - Violation of memory protection/Segmentation fault
程序returns“段错误(核心已转储)”。怎么了?
实施基于示例 - 'Nested' 表单文档 BOOST.SML:
http://boost-experimental.github.io/sml/examples/index.html#nested
SM 用于从 Server 调用方法。 Server用于切换SM中的状态。
#include <boost/sml.hpp>
#include <iostream>
namespace sml = boost::sml;
using namespace std;
template <class = class Dummy>
class Server
{
struct pollEvent{};
struct msgRcdEvent{};
class States
{
public:
States(Server *server): _server(server){}
auto operator()() const noexcept
{
auto msgRcdAction = [this] {
std::cout << "HB server -> msgRcdAction " << std::endl;
_server->recvMsg();
};
auto pollAction = [this] {
std::cout << "HB server -> pollAction " << std::endl;
_server->poll();
};
using namespace sml;
return make_transition_table(
*"idle"_s + event<pollEvent> / pollAction = "Poll"_s,
"Poll"_s + event<msgRcdEvent> / msgRcdAction = "RcdMsg"_s,
"RcdMsg"_s + event<pollEvent> / pollAction = "Poll"_s
);
}
private:
Server *_server{nullptr};
};
public:
Server()
{
_states = new States(this);
_sm = new sml::sm<States>(*_states);
}
void process(){_sm->process_event(pollEvent{});}
void poll(){_sm->process_event(msgRcdEvent{});}
void recvMsg(){_sm->process_event(pollEvent{});}
private:
States *_states{nullptr};
sml::sm<States> *_sm{nullptr};
};
int main()
{
Server<> s{};
s.process();
return 0;
}
段错误是由堆栈溢出引起的。因为 _sm->process_event(...)
是递归调用的。该函数立即处理事件。
为了避免它,我们需要一些排队事件机制而不是立即处理事件。
sml 提供。
这是代码。请参阅评论 1 至 3。
#include <boost/sml.hpp>
#include <iostream>
#include <queue>
namespace sml = boost::sml;
using namespace std;
template <class = class Dummy>
class Server
{
struct pollEvent{};
struct msgRcdEvent{};
class States
{
public:
States(Server *server): _server(server){}
auto operator()() const noexcept
{
auto msgRcdAction =
// 2. Add parameters to lambda expression
// The second parameter is process callable object that is from
// action. The template argument `pollEvent` is the event you want
// to pass to the `process`.
// You can write multiple template arguments.
// e.g.) sml::back::process<pollEvent, msgRcdEvent>
[this] (auto const& /*ev*/, sml::back::process<pollEvent> process) {
std::cout << "HB server -> msgRcdAction " << std::endl;
_server->recvMsg(process);
};
auto pollAction =
[this] (auto const& /*ev*/, sml::back::process<msgRcdEvent> process) {
std::cout << "HB server -> pollAction " << std::endl;
_server->poll(process);
};
using namespace sml;
return make_transition_table(
*"idle"_s + event<pollEvent> / pollAction = "Poll"_s,
"Poll"_s + event<msgRcdEvent> / msgRcdAction = "RcdMsg"_s,
"RcdMsg"_s + event<pollEvent> / pollAction = "Poll"_s
);
}
private:
Server *_server{nullptr};
};
public:
Server()
{
_states = new States(this);
_sm = new sml::sm<States, sml::process_queue<std::queue>>(*_states);
}
void process1(){_sm->process_event(pollEvent{});}
// 3. Invoke process callable object
template <typename Process>
void poll(Process p){ p(msgRcdEvent{});}
template <typename Process>
void recvMsg(Process p){ p(pollEvent{});}
private:
States *_states{nullptr};
// 1. Add `sml::process_queue<std::queue>` template argument to `sml::sm`.
sml::sm<States, sml::process_queue<std::queue>> *_sm{nullptr};
};
int main()
{
Server<> s{};
s.process1();
return 0;
}
sml::back::process<pollEvent>
(评论 2)是一个可调用(类函数)对象,它正在对事件进行排队。您可以调用它而不是 _sm->process_event(...)
(评论 3)。
队列设置为 sm
(注释 1)的模板参数。
程序returns“段错误(核心已转储)”。怎么了?
实施基于示例 - 'Nested' 表单文档 BOOST.SML:
http://boost-experimental.github.io/sml/examples/index.html#nested
SM 用于从 Server 调用方法。 Server用于切换SM中的状态。
#include <boost/sml.hpp>
#include <iostream>
namespace sml = boost::sml;
using namespace std;
template <class = class Dummy>
class Server
{
struct pollEvent{};
struct msgRcdEvent{};
class States
{
public:
States(Server *server): _server(server){}
auto operator()() const noexcept
{
auto msgRcdAction = [this] {
std::cout << "HB server -> msgRcdAction " << std::endl;
_server->recvMsg();
};
auto pollAction = [this] {
std::cout << "HB server -> pollAction " << std::endl;
_server->poll();
};
using namespace sml;
return make_transition_table(
*"idle"_s + event<pollEvent> / pollAction = "Poll"_s,
"Poll"_s + event<msgRcdEvent> / msgRcdAction = "RcdMsg"_s,
"RcdMsg"_s + event<pollEvent> / pollAction = "Poll"_s
);
}
private:
Server *_server{nullptr};
};
public:
Server()
{
_states = new States(this);
_sm = new sml::sm<States>(*_states);
}
void process(){_sm->process_event(pollEvent{});}
void poll(){_sm->process_event(msgRcdEvent{});}
void recvMsg(){_sm->process_event(pollEvent{});}
private:
States *_states{nullptr};
sml::sm<States> *_sm{nullptr};
};
int main()
{
Server<> s{};
s.process();
return 0;
}
段错误是由堆栈溢出引起的。因为 _sm->process_event(...)
是递归调用的。该函数立即处理事件。
为了避免它,我们需要一些排队事件机制而不是立即处理事件。
sml 提供。
这是代码。请参阅评论 1 至 3。
#include <boost/sml.hpp>
#include <iostream>
#include <queue>
namespace sml = boost::sml;
using namespace std;
template <class = class Dummy>
class Server
{
struct pollEvent{};
struct msgRcdEvent{};
class States
{
public:
States(Server *server): _server(server){}
auto operator()() const noexcept
{
auto msgRcdAction =
// 2. Add parameters to lambda expression
// The second parameter is process callable object that is from
// action. The template argument `pollEvent` is the event you want
// to pass to the `process`.
// You can write multiple template arguments.
// e.g.) sml::back::process<pollEvent, msgRcdEvent>
[this] (auto const& /*ev*/, sml::back::process<pollEvent> process) {
std::cout << "HB server -> msgRcdAction " << std::endl;
_server->recvMsg(process);
};
auto pollAction =
[this] (auto const& /*ev*/, sml::back::process<msgRcdEvent> process) {
std::cout << "HB server -> pollAction " << std::endl;
_server->poll(process);
};
using namespace sml;
return make_transition_table(
*"idle"_s + event<pollEvent> / pollAction = "Poll"_s,
"Poll"_s + event<msgRcdEvent> / msgRcdAction = "RcdMsg"_s,
"RcdMsg"_s + event<pollEvent> / pollAction = "Poll"_s
);
}
private:
Server *_server{nullptr};
};
public:
Server()
{
_states = new States(this);
_sm = new sml::sm<States, sml::process_queue<std::queue>>(*_states);
}
void process1(){_sm->process_event(pollEvent{});}
// 3. Invoke process callable object
template <typename Process>
void poll(Process p){ p(msgRcdEvent{});}
template <typename Process>
void recvMsg(Process p){ p(pollEvent{});}
private:
States *_states{nullptr};
// 1. Add `sml::process_queue<std::queue>` template argument to `sml::sm`.
sml::sm<States, sml::process_queue<std::queue>> *_sm{nullptr};
};
int main()
{
Server<> s{};
s.process1();
return 0;
}
sml::back::process<pollEvent>
(评论 2)是一个可调用(类函数)对象,它正在对事件进行排队。您可以调用它而不是 _sm->process_event(...)
(评论 3)。
队列设置为 sm
(注释 1)的模板参数。