简介

boost是C++的一个扩展库,被称为C++准标准库,里面的组件很丰富,并且引用方便,85%的组件只需要引用头文件即可使用。

并且在嵌入式系统也可以很方便的使用,这里介绍一下signal的使用,有点类似Qt里的信号槽。

可以接收静态函数、类成员函数、labmda表达式。

下面这个是使用signal封装的一个事件注册处理模板,使用起来还是很方便的。

代码

模板实现:
#ifndef __EVENT_PROC_H__
#define __EVENT_PROC_H__
#include <iostream>
#include <map>
#include <string>
#include <boost/bind.hpp>
#include "boost/signals2.hpp" using namespace std; #ifndef RTN_FAIL
#define RTN_FAIL -1
#endif #ifndef RTN_SUCCESS
#define RTN_SUCCESS 0
#endif /*----------------------------------类定义-----------------------------------*/
template <typename TypeEvent, typename TypeFunc ,typename TypeFnData, typename TypeFnDataLen>
class TSEventProc
{
public:
TSEventProc() {}
~TSEventProc() {}
int RegEvent(TypeEvent tpEvent, TypeFunc func); // 注册处理函数
int ProcEvent(TypeEvent tpEvent, TypeFnData tpData, TypeFnDataLen tpDataLen); // 处理指令数据 typedef boost::signals2::signal<void(TypeEvent,TypeFnData, TypeFnDataLen)> EventSignal; protected:
map< TypeEvent, EventSignal*> m_mpEventProcMap; // 命令字与处理函数映射表
}; /*----------------------------------类实现-----------------------------------*/
//事件注册
template <typename TypeEvent,typename TypeFunc, typename TypeFnData, typename TypeFnDataLen>
int TSEventProc< TypeEvent, TypeFunc,TypeFnData, TypeFnDataLen>::RegEvent(TypeEvent tpEvent, TypeFunc func)
{
typename map< TypeEvent, EventSignal* >::iterator iter = m_mpEventProcMap.find(tpEvent);
if( iter != m_mpEventProcMap.end() )
{
iter->second->connect(func);
}
else
{
m_mpEventProcMap[tpEvent] = new EventSignal;
m_mpEventProcMap[tpEvent]->connect(func);
} return RTN_SUCCESS;
} //事件处理
template <typename TypeEvent, typename TypeFunc,typename TypeFnData, typename TypeFnDataLen>
int TSEventProc<TypeEvent, TypeFunc,TypeFnData, TypeFnDataLen>::ProcEvent(TypeEvent tpEvent, TypeFnData tpData, TypeFnDataLen tpDataLen)
{
EventSignal *pEventSignal = NULL;
typename map< TypeEvent, EventSignal*>::iterator iter = m_mpEventProcMap.find(tpEvent);
if(iter != m_mpEventProcMap.end())
{
pEventSignal = iter->second;
(*pEventSignal)(tpEvent,tpData,tpDataLen);
}
else
{
cout<<"in ProcEvent, Can't find cmd ["<<tpEvent<<"] process function."<<endl;
return RTN_FAIL;
} return RTN_SUCCESS;
} #endif /* __EVENT_PROC_H__ */
测试代码
#include <QCoreApplication>
#include <iostream> using namespace std; #include "event_proc.h"
#include "boost/bind.hpp" typedef boost::function<void(string, const void *, int)> MSG_FUNCTION3; //测试用的处理函数
void TestCmd(string event,const void * pData, int iLen)
{
char *pcData = (char *)pData;
cout<<"TestCmd: event: "<<event<<endl; if (pcData)
printf("dev: %d, cmd: %d,dataLen: %d\n", pcData[0], pcData[1],iLen);
return;
} //测试用的处理函数
void TestCmd1(string event,const void * pData, int iLen)
{
char *pcData = (char *)pData;
cout<<"TestCmd1: event: "<<event<<endl; if (pcData)
printf("dev: %d, cmd: %d,dataLen: %d\n", pcData[0], pcData[1],iLen);
return;
} //测试用类
class testFuncObject
{
public:
void TestFunc(string event,const void * pData, int iLen)
{
cout<<"testFuncObject::TestFunc: event: "<<event<<endl; char *pcData = (char *)pData;
if (pcData)
printf("testFuncObject::TestFunc, dev: %d, cmd: %d,dataLen: %d\n", pcData[0], pcData[1],iLen);
}
}; int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv); TSEventProc <string, MSG_FUNCTION3,const void*, int> eventMgr;
char Data[32] = {0}; //使用静态函数
eventMgr.RegEvent("event1",TestCmd);
eventMgr.RegEvent("event1",TestCmd1);
eventMgr.RegEvent("event2",TestCmd); //使用lambda表达式
eventMgr.RegEvent("event2",[](string event,const void * pData, int iLen){
cout<<"use labmda: event: "<<event<<endl;
}); //测试使用类成员函数
testFuncObject testobj;
eventMgr.RegEvent("event2",boost::bind(&testFuncObject::TestFunc, &testobj, _1,_2,_3)); Data[0] = 31;
Data[1] = 2;
//event1事件处理
eventMgr.ProcEvent("event1", Data, (int)sizeof(Data));
Data[1] = 3;
//event2事件处理
eventMgr.ProcEvent("event2", Data, (int)sizeof(Data)); return a.exec();
}

上面测试代码是在qt的工程里写的,所以有 QCoreApplication a(argc, argv); 和 a.exec();

运行结果
TestCmd: event: event1
dev: 31, cmd: 2,dataLen: 32
TestCmd1: event: event1
dev: 31, cmd: 2,dataLen: 32
TestCmd: event: event2
dev: 31, cmd: 3,dataLen: 32
use labmda: event: event2
testFuncObject::TestFunc: event: event2
testFuncObject::TestFunc, dev: 31, cmd: 3,dataLen: 32

boost之signal的使用的更多相关文章

  1. boost::signals::signal的使用方法

    吃力的讲完boost::signals的ppt.然后接着就是做练习题. 通过讲ppt,发现有一句话说的真好:你自己知道是一回事.你能给别人讲明确又是另外一回事.真的有些东西你自己理解,可是用语言去非常 ...

  2. boost之signal

    boost里的signal是一个模板类,不区分信号种类,产生信号统一用()调用操作符. 1.回调普通函数代码示例: #include <iostream> #include <str ...

  3. Boost信号/槽signals2

    信号槽是Qt框架中一个重要的部分,主要用来解耦一组互相协作的类,使用起来非常方便.项目中有同事引入了第三方的信号槽机制,其实Boost本身就有信号/槽,而且Boost的模块相对来说更稳定. signa ...

  4. c++中的signal机制

    简介 signal是为了解决类之间通信的问题而出现的,更深入的原因是面向对象讲究封装,但是封装必然导致类之间沟通困难,但是使用接口的方式又太重量级--需要写很多代码,而且会导致接口爆炸 比如你需要把一 ...

  5. BOOST::Signals2

    /* Andy is going to hold a concert while the time is not decided. Eric is a fans of Andy who doesn't ...

  6. 函数指针玩得不熟,就不要自称为C语言高手(函数指针是解耦对象关系的最佳利器,还有signal)

    记得刚开始工作时,一位高手告诉我说,longjmp和setjmp玩得不熟,就不要自称为C语言高手.当时我半信半疑,为了让自己向高手方向迈进,还是花了一点时间去学习longjmp和setjmp的用法.后 ...

  7. boost事件处理

    尽管这个库的名字乍一看好象有点误导,但实际上并不是如此. Boost.Signals 所实现的模式被命名为 '信号至插槽' (signal to slot).它基于下面概念:当相应的信号被发出时.相关 ...

  8. boost------signals2的使用1(Boost程序库完全开发指南)读书笔记

    signals2基于Boost的另一个库signals,实现了线程安全的观察者模式.在signals2库中,观察者模式被称为信号/插槽(signals and slots),他是一种函数回调机制,一个 ...

  9. boost------signals2的使用2(Boost程序库完全开发指南)读书笔记

    1.应用于观察者模式 本小节将使用signals2开发一个完整的观察者模式示例程序,用来演示信号/插槽的用法.这个程序将模拟一个日常生活场景:客人按门铃,门铃响,护士开门,婴儿哭闹. Ring.h: ...

随机推荐

  1. 数据可视化之DAX篇(十八)收藏 | DAX代码格式指南

    https://zhuanlan.zhihu.com/p/64422599 为什么要进行格式化? DAX 是一种函数式语言,正如我们已经学习的或者看到的,DAX 代码中总有一些函数带有几个参数,而参数 ...

  2. 循序渐进VUE+Element 前端应用开发(15)--- 用户管理模块的处理

    在前面随笔介绍了ABP+Vue前后端的整合处理,包括介绍了ABP的后端设计,以及前端对ABP接口API的ES6的封装,通过JS的继承类处理,极大减少了重复臃肿的代码,可以简化对后端API接口的封装,而 ...

  3. bzoj1680[Usaco2005 Mar]Yogurt factory*&&bzoj1740[Usaco2005 mar]Yogurt factory 奶酪工厂*

    bzoj1680[Usaco2005 Mar]Yogurt factory bzoj1740[Usaco2005 mar]Yogurt factory 奶酪工厂 题意: n个月,每月有一个酸奶需求量( ...

  4. SpringBoot学习笔记(十七:异步调用)

    @ 目录 1.@EnableAsync 2.@Async 2.1.无返回值的异步方法 2.1.有返回值的异步方法 3. Executor 3.1.方法级别重写Executor 3.2.应用级别重写Ex ...

  5. idea 项目启动console卡在Connected to the target VM, address: '127.0.0.1:51140', transport: 'socket'不动了

  6. 【Python学习笔记六】获取百度搜索结果以及百度返回“百度安全验证”问题解决

    1.获取百度搜索结果页面主要是修改百度搜索url中的参数实现,例如查询的关键字为wd: 举例:https://www.baidu.com/s?wd=python",这样就可以查询到‘pyth ...

  7. PyCharm+PyQt5+Qt Designer配置

    配置前提 因为本机已经配置完毕了,本次使用的是虚拟机中的Win7系统,Win10系统操作步骤完全一样,无任何区别 PyCharm (这个不多说,官网下载安装,我是用的是2019.3版本) Python ...

  8. C语言中对文件的读写的一些浅显理解

    前述:基于上学期完成的数据结构的课程设计,对于老师的提出要求实现的基础上,自己在使用过程中发现每次打开程序都需要重新输入数据,于是便决定,将文件读写功能加入此次课程设计中,以下是我的一些心得和浅显理解 ...

  9. PHP入门之类型与运算符

    前言 PHP对于大部分人来说,是比较容易入门的.笔者也是刚学习不久,所以就把自己学习的基础知识进行总结和整理.第一部分是类型与运算符.如果你想学习PHP,可以参考PHP学习手册学习,任何一本教学资料也 ...

  10. Raid0,1,5,10,50

    raid0 就是把多个硬盘合并成1个逻辑盘使用,数据读写时对各硬盘同时操作,不同硬盘写入不同数据,速度快. **最少需要2块硬盘 raid1 同时对2个硬盘读写(同样的数据).强调数据的安全性.损坏一 ...