zoukankan      html  css  js  c++  java
  • 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
    ", 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
    ", 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
    ", 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
    
  • 相关阅读:
    oracle序列的使用
    oracle学习
    项目部署的一些问题
    mybatis的resultMap与resultType的区别
    react-router-dom路由switch使用
    Json.parse 和Json.stringfy()用法
    页面中js按顺序加载完全的方法
    伪数组转为真数组
    import和export的作用
    Object.entries()
  • 原文地址:https://www.cnblogs.com/fensnote/p/13436455.html
Copyright © 2011-2022 走看看