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: ...
随机推荐
- Python 图像处理 OpenCV (13): Scharr 算子和 LOG 算子边缘检测技术
前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...
- python 并发专题(六):协程相关函数以及实现(gevent)
文档资源 http://sdiehl.github.io/gevent-tutorial/ 一.协程实现 线程和协程 既然我们上面也说了,协程也被称为微线程,下面对比一下协程和线程: 线程之间需要上下 ...
- Django框架08 /聚合查询、分组、F/Q查询、原生sql相关
Django框架08 /聚合查询.分组.F/Q查询.原生sql相关 目录 Django框架08 /聚合查询.分组.F/Q查询.原生sql相关 1. 聚合查询 2. 分组 3. F查询和Q查询 4. o ...
- 也来谈谈python编码
一.coding:utf-8 让我们先来看一个示例,源码文件是utf-8格式: print('你好 python') 当使用python2执行该程序时会收到一下报错: File "./hel ...
- JavaScript:父页面与Iframe页面方法互调
父页面调用Iframe页面中的函数 以上是父页面中定义的iframe,注意添加name属性 在父页面中调用mapFrame的ShowMyLocation方法 Iframe页面调用父页面的方法 直接在I ...
- Spring入门案例
一.Spring基本介绍 1.什么是Spring Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control: 反转控制 ...
- Ethical Hacking - Web Penetration Testing(2)
INFORMATION GATHERING IP address. Domain name Info. Technologies used. Other websites on the same se ...
- 手把手带你玩转 DialogFragment
前言 本文已经收录到我的 Github 个人博客,欢迎大佬们光临寒舍: 我的 GIthub 博客 思维导图 一.为什么要学习 DialogFragment 你还在用 Dialog 吗? 你还在经常烦恼 ...
- idea 自动生成try/catch代码块的快捷键
好像每个人的快捷键可能不同:我的是 Alt+Shift+Z 网上查的是 Ctrl+Alt+T 如果都不是可以点选工具栏生成try/catch(并可查看到自己的快捷键是什么):Code->Su ...
- 题解 SP3734 【PERIODNI - Periodni】
考虑用\(DP\)和组合数学来解决. 因为原图像不规则的形状不好处理,所以先用笛卡尔树(性质为小根堆)将其划分成一个一个的矩形. 发现在笛卡尔树上的每个节点都对应一个矩形,矩形高为\(h_x-h_{f ...