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
目录
相关文章
|
5月前
19.3 Boost Asio 多线程通信
多线程服务依赖于两个通用函数,首先`boost::bind`提供了一个高效的、简单的方法来创建函数对象和函数对象适配器,它的主要功能是提供了一种将函数和它的参数绑定到一起的方法,这种方法可以将具有参数的成员函数、普通函数以及函数对象转化为不带参数的函数对象。当参数绑定后则下一步就需要使用多线程功能,Boost库中提供了`boost::thread`库,`boost::thread`可以用于创建线程、启动线程、等待线程执行结束以及线程间通信等多种操,有了这两个关键库那么我们只需要`accept.accept(*sock)`等待套接字上线,当有套接字上线后则自动创建`MyThread`子线程,
47 0
19.3 Boost Asio 多线程通信
|
3月前
boost asio多线程
boost asio多线程
|
10月前
|
存储 固态存储 Linux
深入学习tombstone和signal
深入学习tombstone和signal
130 0
深入学习tombstone和signal
|
网络协议 编译器 消息中间件
|
调度 .NET 开发框架
Boost-ioservices介绍
IO模型 io_service对象是asio框架中的调度器,所有异步io事件都是通过它来分发处理的(io对象的构造函数中都需要传入一个io_service对象)。     asio::io_service io_service;    asio::ip::tcp::socket socket(i...
1094 0
|
C++
Boost相关资料
Boost官网 文档: http://www.boost.org/doc/libs/1_64_0/ 中文 http://zh.highscore.de/cpp/boost/introduction.
943 0
|
Linux
Why does pthread_cond_signal not work?【转】
转自:http://stackoverflow.com/questions/16819169/why-does-pthread-cond-signal-not-work# 0 down vote favorite   I am currently learing all around POSIX threads (pthread).
838 0
|
存储 物联网
|
数据可视化 算法
BOOST Voronoi Visualizer
BOOST Voronoi Visualizer eryar@163.com Abstract. The Voronoi extension of the Boost.Polygon library provides functionality to construct a Voronoi dia...
1332 0