boost之signal的使用
简介
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的使用的更多相关文章
- boost::signals::signal的使用方法
吃力的讲完boost::signals的ppt.然后接着就是做练习题. 通过讲ppt,发现有一句话说的真好:你自己知道是一回事.你能给别人讲明确又是另外一回事.真的有些东西你自己理解,可是用语言去非常 ...
- boost之signal
boost里的signal是一个模板类,不区分信号种类,产生信号统一用()调用操作符. 1.回调普通函数代码示例: #include <iostream> #include <str ...
- Boost信号/槽signals2
信号槽是Qt框架中一个重要的部分,主要用来解耦一组互相协作的类,使用起来非常方便.项目中有同事引入了第三方的信号槽机制,其实Boost本身就有信号/槽,而且Boost的模块相对来说更稳定. signa ...
- c++中的signal机制
简介 signal是为了解决类之间通信的问题而出现的,更深入的原因是面向对象讲究封装,但是封装必然导致类之间沟通困难,但是使用接口的方式又太重量级--需要写很多代码,而且会导致接口爆炸 比如你需要把一 ...
- BOOST::Signals2
/* Andy is going to hold a concert while the time is not decided. Eric is a fans of Andy who doesn't ...
- 函数指针玩得不熟,就不要自称为C语言高手(函数指针是解耦对象关系的最佳利器,还有signal)
记得刚开始工作时,一位高手告诉我说,longjmp和setjmp玩得不熟,就不要自称为C语言高手.当时我半信半疑,为了让自己向高手方向迈进,还是花了一点时间去学习longjmp和setjmp的用法.后 ...
- boost事件处理
尽管这个库的名字乍一看好象有点误导,但实际上并不是如此. Boost.Signals 所实现的模式被命名为 '信号至插槽' (signal to slot).它基于下面概念:当相应的信号被发出时.相关 ...
- boost------signals2的使用1(Boost程序库完全开发指南)读书笔记
signals2基于Boost的另一个库signals,实现了线程安全的观察者模式.在signals2库中,观察者模式被称为信号/插槽(signals and slots),他是一种函数回调机制,一个 ...
- boost------signals2的使用2(Boost程序库完全开发指南)读书笔记
1.应用于观察者模式 本小节将使用signals2开发一个完整的观察者模式示例程序,用来演示信号/插槽的用法.这个程序将模拟一个日常生活场景:客人按门铃,门铃响,护士开门,婴儿哭闹. Ring.h: ...
随机推荐
- js数组算法题01
题目:随机生成一个长度为 10 的整数类型的数组,例如 [2, 10, 3, 4, 5, 11, 10, 11, 20],将其排列成一个新数组,要求新数组形式如下,例如 [[2, 3, 4, 5], ...
- Scala 面向对象(二):package 包 (一) 入门
1 Scala包的基本介绍 和Java一样,Scala中管理项目可以使用包,但Scala中的包的功能更加强大,使用也相对复杂些,下面我们学习Scala包的使用和注意事项. 2 Scala包快速入门 使 ...
- linux专题(一):小白的开始以及相关的学习链接
转载自:https://www.cnblogs.com/ggjucheng/archive/2011/12/16/2290158.html 学习Linux也有一阵子了,这过程中磕磕撞撞的,遇到了问题, ...
- 《你还在写sql语句吗?》人生苦短,进入MybatisPlus的丝滑体验
一.发展历程 依稀记得大学期间,类中写sql语句的日子,一个sql语句占据了大部分时间,到后来hibernate的出现算是解决了这一痛点.工作 后,我们又接触到了mybatis这样的框架,瞬间感觉这个 ...
- 手写简易的Mybatis
手写简易的Mybatis 此篇文章用来记录今天花个五个小时写出来的简易版mybatis,主要实现了基于注解方式的增删查改,目前支持List,Object类型的查找,参数都是基于Map集合的,可以先看一 ...
- OSCP Learning Notes - Exploit(8)
Tools: 3. hydra Hydra v8.9.1 (c) 2019 by van Hauser/THC - Please do not use in military or secret se ...
- Spring IoC深入理解
本文相关代码(来自官方源码spring-test模块)请参见spring-demysify org.springframework.mylearntest包下. 三种注入方式 1.构造方法注入 pub ...
- [jvm] -- 垃圾收集器篇
垃圾收集器 Serial 收集器 单线程收集器,不仅仅意味着它只会使用一条垃圾收集线程去完成垃圾收集工作,更重要的是它在进行垃圾收集工作的时候必须暂停其他所有的工作线程( "Stop The ...
- [jvm] -- 类文件结构篇
类文件结构 结构图 魔数 头四个字节,作用是确定这个文件是否为一个能被虚拟机接收的 Class 文件. Class 文件版本 第五和第六是次版本号,第七和第八是主版本号. 高版本的 Java 虚拟机 ...
- DJANGO-天天生鲜项目从0到1-008-列表页
本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...