C++ 对象间通讯机制 框架实现
- // SignalSlot.h: interface for the CSignalSlot class.
- //
- //////////////////////////////////////////////////////////////////////
- #if !defined(AFX_SIGNALSLOT_H__A686E4F2_5477_4D5E_9A1F_03883EEBAB1E__INCLUDED_)
- #define AFX_SIGNALSLOT_H__A686E4F2_5477_4D5E_9A1F_03883EEBAB1E__INCLUDED_
- #include <Afxtempl.h>
- #if _MSC_VER > 1000
- #pragma once
- #endif // _MSC_VER > 1000
- // //
- //--------------------------------------------------------------------------------------------
- // 静态slot接口函数类型指针定义
- typedef int (__cdecl *SS_STAIC_SLOTFUNC)(void *pSelf,int slot_F,void *pSrc,void *pDes);
- // 数据结构定义
- struct FuncItem
- {
- bool is_use; //是否使用
- int signal_F;
- int slot_F;
- };
- struct SSItem
- {
- bool is_use; //是否使用
- void* signal_pSelf;
- void* slot_pSelf;
- void* slot_pFunc;
- CArray<FuncItem,FuncItem>*pFuncArray;
- };
- //----------------------------------------------------------------------------------------------------------------------
- /*
- 宏定义1: 信号槽类注册
- 说明: 信号槽(接收方)类定义需要使用该宏声明
- 在类定义最开始位置声明,结尾不需要冒号。例子如下所示:
- class CTest
- {
- SS_REGISTER(CTest)
- public:
- ...
- }
- 参数: ClassName 为类名称
- 宏展开: 定义了一个公有静态函数:
- SS_STATIC_SLOT: 函数名称
- pSelf: 类对象指针
- slot_F: 槽函数ID (成员函数指针转换得到)
- pSrc: 信号发送方输入参数void通用指针
- pDes: 返回参数内存指针(由调用方提供)
- */
- #define SS_REGISTER(ClassName) \
- public: static int _SS_STATIC_SLOT_(void *pSelf,int slot_F,void *pSrc,void *pDes)\
- {\
- typedef int(ClassName::*SLOTFUNC)(void*pSrc,void*pDes=NULL);\
- SLOTFUNC slot_Func;\
- int TEMP = (int)(&slot_Func);\
- *((int*)(TEMP)) = slot_F;\
- int res = (((ClassName*)(pSelf))->*slot_Func)(pSrc,pDes);\
- return res;\
- }
- // 宏定义2: 信号函数定义
- #define SS_SIGNAL(ClassName,FuncName) \
- int FuncName(void*pSrc,void*pDes=NULL)\
- {\
- typedef int(ClassName::*SLOTFUNC)(void*,void*);\
- SLOTFUNC pfunc = &ClassName::FuncName;\
- int funcID = *((int*)((int)(&pfunc)));\
- return CSignalSlot::SignalSS(this,funcID,pSrc,pDes);\
- }
- // 宏定义3: 初始化连接
- #define SS_INITE(signalSelf,slotSelf,res) \
- *res = CSignalSlot::IniteSS(signalSelf,slotSelf,(slotSelf)->_SS_STATIC_SLOT_);
- // 宏定义4: 解除对象连接
- #define SS_CLOSE(signalSelf,slotSelf,res) \
- *res = CSignalSlot::CloseSS(signalSelf,slotSelf);
- // 宏定义5: 连接功能函数
- #define SS_CONNECT(signalClassName,signalSelf,signalFunc,slotClassName,slotSelf,slotFunc,res) \
- {\
- typedef int(signalClassName::*SIGNAL_PF)(void*,void*);\
- typedef int(slotClassName::*SLOT_PF)(void*,void*);\
- SIGNAL_PF Signal_F = &signalClassName::signalFunc;\
- SLOT_PF slot_F = &slotClassName::slotFunc;\
- *res = CSignalSlot::ConnectSS(signalSelf,*((int*)((int)(&Signal_F))),slotSelf,*((int*)((int)(&slot_F))));\
- }
- // 宏定义6: 断开功能连接
- #define SS_DISCONNECT(signalClassName,signalSelf,signalFunc,slotClassName,slotSelf,slotFunc,res) \
- {\
- typedef int(signalClassName::*SIGNAL_PF)(void*,void*);\
- typedef int(slotClassName::*SLOT_PF)(void*,void*);\
- SIGNAL_PF Signal_F = &signalClassName::signalFunc;\
- SLOT_PF slot_F = &slotClassName::slotFunc;\
- *res = CSignalSlot::DisConnectSS(signalSelf,*((int*)((int)(&Signal_F))),slotSelf,*((int*)((int)(&slot_F))));\
- }
- // 宏定义7: 初始化连接(3与5的功能组合)
- #define SS_INICONNECT(signalClassName,signalSelf,signalFunc,slotClassName,slotSelf,slotFunc,res) \
- SS_INITE(signalSelf,slotSelf,res)\
- if(*res!=-)\
- SS_CONNECT(signalClassName,signalSelf,signalFunc,slotClassName,slotSelf,slotFunc,res);
- //------------------------------------------------------------------------------------------------------------------------------
- class CSignalSlot
- {
- public:
- static int DisConnectSS(void* signal_pSelf,int signal_F,void* slot_pSelf,int slot_F);
- static int CloseSS(void *signal_pSelf,void*slot_pSelf);
- static int IniteSS(void* signal_pSelf,void* slot_pSelf,SS_STAIC_SLOTFUNC slot_pFunc);
- static int SignalSS(void *signal_pSelf,int signal_F,void *pSrc,void *pDes=NULL);
- static int ConnectSS(void* signal_pSelf,int signal_F,void* slot_pSelf,int slot_F);
- CSignalSlot();
- virtual ~CSignalSlot();
- private:
- static void CloseFuncArray(CArray<FuncItem,FuncItem>*pFuncArray);
- static CArray<SSItem,SSItem>m_SSArray;
- static int m_loopback;
- };
- #endif // !defined(AFX_SIGNALSLOT_H__A686E4F2_5477_4D5E_9A1F_03883EEBAB1E__INCLUDED_)
- // SignalSlot.cpp: implementation of the CSignalSlot class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "SignalSlot.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CArray<SSItem,SSItem> CSignalSlot::m_SSArray;
- int CSignalSlot::m_loopback = ;
- CSignalSlot::CSignalSlot()
- {
- }
- CSignalSlot::~CSignalSlot()
- {
- }
- //初始化对象连接 建立非对称连接 signal对象可以往slot对象发消息 一条单向通信链路定义为一个连接项
- // 返回值:1 成功 0 已存在该连接 -1 添加失败
- int CSignalSlot::IniteSS(void* signal_pSelf,void* slot_pSelf,SS_STAIC_SLOTFUNC slot_pFunc)
- {
- int len = CSignalSlot::m_SSArray.GetSize();
- SSItem tItem;
- int nPos = -;
- // 扫描是否已存在该连接(同时记录下第一个位置内存项记录)
- for(int i=;i<len;i++)
- {
- tItem = CSignalSlot::m_SSArray.GetAt(i);
- if(true==tItem.is_use)
- {
- if(signal_pSelf==tItem.signal_pSelf && slot_pSelf==tItem.slot_pSelf)
- {
- return ; // 已存在该连接
- }
- }
- else
- {
- if(-==nPos)
- {
- nPos = i;// 记住第一个扫描到的位置用内存项位置
- }
- }
- }
- //增加新连接
- if(nPos!=-)// 占用空闲位置项
- {
- tItem = CSignalSlot::m_SSArray.GetAt(nPos);
- tItem.is_use = TRUE;
- tItem.signal_pSelf = signal_pSelf;
- tItem.slot_pSelf = slot_pSelf;
- tItem.slot_pFunc = slot_pFunc;
- CSignalSlot::m_SSArray.SetAt(nPos,tItem);
- return ;
- }else //新增位置项
- {
- tItem.is_use = TRUE;
- tItem.signal_pSelf = signal_pSelf;
- tItem.slot_pSelf = slot_pSelf;
- tItem.slot_pFunc = slot_pFunc;
- tItem.pFuncArray = new CArray<FuncItem,FuncItem>;
- CSignalSlot::m_SSArray.Add(tItem);
- return ;
- }
- }
- // 信号|槽连接: <signal对象+成员函数ID,slot对象+成员函数>作为一个连接项
- // 返回值:1:成功 0:已存在该连接项 -1:添加失败
- int CSignalSlot::ConnectSS(void* signal_pSelf,int signal_F,void* slot_pSelf,int slot_F)
- {
- int len = CSignalSlot::m_SSArray.GetSize();
- SSItem sItem;
- FuncItem fItem;
- int nPos = -;
- for (int i=;i<len;i++)
- {
- sItem = CSignalSlot::m_SSArray.GetAt(i);
- if(signal_pSelf==sItem.signal_pSelf && slot_pSelf==sItem.slot_pSelf && true==sItem.is_use)
- {
- int sum = sItem.pFuncArray->GetSize();
- for(int k=;k<sum;k++)
- {
- fItem= sItem.pFuncArray->GetAt(k);
- if(true==fItem.is_use)
- {
- if(signal_F==fItem.signal_F && slot_F==fItem.slot_F)
- {
- return ; //已存在该连接
- }
- }else
- {
- if(-==nPos)
- {
- nPos = k;
- }
- }
- }
- // 新增连接
- fItem.is_use = true;
- fItem.signal_F = signal_F;
- fItem.slot_F = slot_F;
- if(nPos!=-)
- {
- sItem.pFuncArray->SetAt(nPos,fItem);
- return ;
- }else
- {
- sItem.pFuncArray->Add(fItem);
- return ;
- }
- }
- }
- return -; // 对象连接没有初始化
- }
- // 返回值: 调用槽的执行数目(每调用一个槽函数,返回值加1)
- int CSignalSlot::SignalSS(void *signal_pSelf,int signal_F,void *pSrc, void *pDes)
- {
- int res = ;
- int len = CSignalSlot::m_SSArray.GetSize();
- for(int i=;i<len;i++)
- {
- SSItem ssitem = CSignalSlot::m_SSArray.GetAt(i);
- if(ssitem.is_use == true && signal_pSelf==ssitem.signal_pSelf) //找到对象连接
- {
- int sum = ssitem.pFuncArray->GetSize();
- for(int k=;k<sum;k++)
- {
- FuncItem fitem = ssitem.pFuncArray->GetAt(k);
- if(fitem.is_use==true && signal_F==fitem.signal_F) //找到信号|槽连接
- {
- ////////////////////////////////////////////////////////////////////////////
- if(CSignalSlot::m_loopback>) //判断是否出现回环(避免信号函数的嵌套调用)
- {
- CSignalSlot::m_loopback = ; //清除嵌套计数
- return ; // 中断返回
- }
- CSignalSlot::m_loopback += ;
- /////////////////////////////////////////////////////////////////////////////
- SS_STAIC_SLOTFUNC tempFunc = (SS_STAIC_SLOTFUNC)ssitem.slot_pFunc;
- tempFunc(ssitem.slot_pSelf,fitem.slot_F,pSrc,pDes); //通过静态槽接口函数发起调用
- res+=;
- }
- }
- }
- }
- CSignalSlot::m_loopback=; //清除嵌套计数
- return res;
- }
- // 关闭删除对象连接(单向)
- // 返回值:>0 成功 0 已不存在该连接 -1 删除失败
- int CSignalSlot::CloseSS(void *signal_pSelf, void *slot_pSelf)
- {
- int len = CSignalSlot::m_SSArray.GetSize();
- SSItem sItem;
- int res = ;
- for(int i=;i<len;i++)
- {
- sItem = CSignalSlot::m_SSArray.GetAt(i);
- if(false==sItem.is_use)
- {
- continue;
- }
- if(NULL==signal_pSelf)
- {
- if(slot_pSelf==sItem.slot_pSelf)
- {
- sItem.is_use = false;
- CSignalSlot::CloseFuncArray(sItem.pFuncArray);
- res+=;
- }
- }else if(NULL==slot_pSelf)
- {
- if(signal_pSelf==sItem.signal_pSelf)
- {
- sItem.is_use = false;
- CSignalSlot::CloseFuncArray(sItem.pFuncArray);
- res+=;
- }
- }else if(signal_pSelf==sItem.signal_pSelf && slot_pSelf==sItem.slot_pSelf)
- {
- sItem.is_use = false;
- CSignalSlot::CloseFuncArray(sItem.pFuncArray);
- res+=;
- break;
- }
- }
- return res;
- }
- // 删除信号槽连接
- // 返回值:1 成功 0 已不存在该连接 -1 删除失败
- int CSignalSlot::DisConnectSS(void *signal_pSelf, int signal_F, void *slot_pSelf, int slot_F)
- {
- int len = CSignalSlot::m_SSArray.GetSize();
- SSItem sItem;
- for (int i=;i<len;i++)
- {
- sItem = CSignalSlot::m_SSArray.GetAt(i);
- if(signal_pSelf==sItem.signal_pSelf && slot_pSelf==sItem.slot_pSelf &&true==sItem.is_use)
- {
- int sum = sItem.pFuncArray->GetSize();
- FuncItem item;
- for(int k=;k<sum;k++)
- {
- item = sItem.pFuncArray->GetAt(k);
- if(signal_F==item.signal_F && slot_F==item.slot_F)
- {
- item = sItem.pFuncArray->GetAt(k);
- item.is_use = false;
- sItem.pFuncArray->SetAt(k,item);
- return ; //删除连接
- }
- }
- }
- }
- return ; // 对象连接没有初始化
- }
- void CSignalSlot::CloseFuncArray(CArray<FuncItem,FuncItem>*pFuncArray)
- {
- int sum = pFuncArray->GetSize();
- FuncItem item;
- for(int k=;k<sum;k++)
- {
- item = pFuncArray->GetAt(k);
- item.is_use = false;
- pFuncArray->SetAt(k,item);
- }
- }
C++ 对象间通讯机制 框架实现的更多相关文章
- 一篇文章了解相见恨晚的 Android Binder 进程间通讯机制【转】
本文转载自:https://blog.csdn.net/freekiteyu/article/details/70082302 Android-Binder进程间通讯机制 概述 最近在学习Binder ...
- Android Binder 进程间通讯机制梳理
什么是 Binder ? Binder是Android系统中进程间通讯(IPC)的一种方式,也是Android系统中最重要的特性之一.Binder的设计采用了面向对象的思想,在Binder通信模型的四 ...
- 如何才能学到Qt的精髓——信号槽之间的无关性,提供了绝佳的对象间通讯方式,QT的GUI全是自己的一套,并且完全开源,提供了一个绝好机会窥视gui具体实现
姚冬,中老年程序员 叶韵.KY Xu.赵奋强 等人赞同 被邀请了很久了,一直在思考,今天终于下决心开始写回答. 这个问题的确是够大的,Qt的代码规模在整个开源世界里也是名列前茅的,这么大的项目其中的精 ...
- C#进程间通讯或同步的框架引荐
这篇文章主要介绍了一个进程间通讯同步的C#框架,代码具有相当的稳定性和可维护性,随着.NET的开源也会被注入更多活力,推荐!需要的朋友可以参考下 0.背景简介 微软在 .NET 框架中提供了多种实用 ...
- java 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)
参考文章:http://ifeve.com/java-concurrency-thread-directory/ 其中的竞态,线程安全,内存模型,线程间的通信,java ThreadLocal类小节部 ...
- 【转】JAVA 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)
原文地址:https://www.cnblogs.com/edenpans/p/6020113.html 参考文章:http://ifeve.com/java-concurrency-thread-d ...
- android 进程间通信 messenger 是什么 binder 跟 aidl 区别 intent 进程间 通讯? android 消息机制 进程间 android 进程间 可以用 handler么 messenger 与 handler 机制 messenger 机制 是不是 就是 handler 机制 或 , 是不是就是 消息机制 android messenge
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha messenger 是什么 binder 跟 aidl 区别 intent 进程间 通讯 ...
- ACE框架 基于共享内存的进程间通讯
ACE框架将基于共享内存的进程间通讯功能,如其它IO组件或IPC组件一样,设计成三个组件.流操作组件ACE_MEM_Stream,连接器组件ACE_MEM_Connector,以及接收连接组件ACE_ ...
- Node.js - 阿里Egg的多进程模型和进程间通讯
前言 最近用Egg作为底层框架开发项目,好奇其多进程模型的管理实现,于是学习了解了一些东西,顺便记录下来.文章如有错误, 请轻喷 为什么需要多进程 伴随科技的发展, 现在的服务器基本上都是多核cpu的 ...
随机推荐
- call 和 apply的定义和区别?
1.方法定义 call方法: 语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象. 说明: call ...
- 004 gcc 编译 C/C++ 默认使用哪个标准
0. 前言 我挺久没碰 C,不想就这么忘了,最近重温了一些相关知识 1. C 语言的几种"方言" 简单地说,有这么几种常见的 年份 名称 1983 ANSI C 1987 C87 ...
- Struts学习(一)
1.Struts开发基础 1.1 MVC的基本概念 mvc将一个应用系统的输入.处理和输出流程按照Model(模型).View(视图)和Controller(控制器)三部分进行分离,划分成模型层.视 ...
- Codeforces 1255E Send Boxes to Alice(前缀和+枚举+数论)
我们考虑前缀和sum[i],如果将a[i+1]中的一个塞入a[i]中,则不影响sum[i+1],但是sum[i]++,如果将a[i]中的一个塞入a[i+1],则不影响sum[i+1],但是sum[i] ...
- php-redis的配置与使用
从此处下载 https://codeload.github.com/phpredis/phpredis/zip/develop 也就php-redis的安装包,在zip格式,在windows下解压,将 ...
- thinkphp5 验证码出不来的常见问题
对于thinkphp如何实现验证码,我这里就不介绍了.直接看之前的文章 http://www.cnblogs.com/qqblog/p/6639419.html.下面,我能想出来的是,我自己在开发过程 ...
- oracle数据库中的存储过程
存储过程是一组为了完成特定功能的sql语句集,是一段sql代码片段,经编译后存储在数据库中,用户通过指定存储过程的名字并给出参数(如果存储过程存在参就给出,不存在就不用给出参数)来执行它.因为它是一段 ...
- 50. Pow(x, n) (JAVA)
Implement pow(x, n), which calculates x raised to the power n(xn). Example 1: Input: 2.00000, 10 Out ...
- visual studio 2013 生成依赖项关系图出错
开始是说无法连接到sql服务器,我安装卸载localdb http://www.microsoft.com/zh-cn/download/details.aspx?id=29062 下载 CHS\x6 ...
- JavaEE高级-SpringMVC学习笔记
*SpringMVC概述 - Spring为展示层提供的基于MVC设计理念的优秀Web框架,是目前最主流的MVC框架之一 - Spring3.0后全面超越Struts2,成为最优秀的MVC框架 - S ...