C代码模拟IOC
用途
一个模块记录设备诸多状态,当任意一个状态发生变化时,会执行对应的回调操作
实现思想
将设备状态进行备份,如果设备最新状态变化,可以比较出哪个状态发生变化,进而执行操作
状态被收束到结构体中,需要将每个结构体成员的地址记录,并且在修改过程中需要将该地址的成员变量进行数据类型的强制转换,以保证不会越界操作到其他的成员数据。
代码
/*ioc.c*/
/**
* @description: 检查数据更改
* @param {IOC} *com
* @param {int} size
* @return {*}
*/
void ioc_check(IOC *com,int size)
{
for(int i = 0;i<size;i++)
{
if(com[i].size == 1)
{
if(*((char *)com[i].addr1) != *((char *)com[i].addr2))
{
*((char *)com[i].addr2) = *((char *)com[i].addr1);
com[i].callback();
}
}
if(com[i].size == 2)
{
if(*((short *)com[i].addr1) != *((short *)com[i].addr2))
{
*((short *)com[i].addr2) = *((short *)com[i].addr1);
com[i].callback();
}
}
if(com[i].size == 4)
{
if(*((int *)com[i].addr1) != *((int *)com[i].addr2))
{
*((int *)com[i].addr2) = *((int *)com[i].addr1);
com[i].callback();
}
}
}
}
/*ioc.h*/
typedef struct{
void *addr1;
void *addr2;
int size;
void (*callback)(void);
}IOC;
char* filter(char *s,char ch);
/**
* @description:
* s1 状态结构体
* s2 状态结构体备份
* type2 状态结构体的类型
* member 状态结构体的一个成员
* fun 回调函数
* com IOC数据类型的一个变量
* type 填入IOC数据类型
* @return {*}
*/
#define Init(s1,s2,type2,member,fun,com,type) \
{\
((type*)com)->addr1 = (unsigned int *)&(((type2*)s1)->member);\
((type*)com)->addr2 = (unsigned int *)&(((type2*)s2)->member);\
((type*)com)->size = sizeof(((type2*)s1)->member);\
((type*)com)->callback = fun;\
}
//使用片段
//#define IOC_MAX_SIZE 13
//static IOC p[IOC_MAX_SIZE];
//memset(&dev_thermostat_back,0xff,sizeof(CONTROL_THERMOSTAT));
//Init(&dev_thermostat,&dev_thermostat_back,CONTROL_THERMOSTAT,t_mode,f_t_mode,&p[0],IOC);
//Init(&dev_thermostat,&dev_thermostat_back,CONTROL_THERMOSTAT,windspeed,f_windspeed_air,&p[1],IOC);
使用方式
1、设备状态结构体及备份创建。结构体设计上使用单字节对齐方式。
2、使用Init函数进行成员地址及回调函数绑定
3、使用ioc_check函数进行监测状态变化。ioc_check可以定时执行;或者等待信号量来临执行。
标签:状态,thermostat,int,IOC,代码,dev,com,模拟 From: https://www.cnblogs.com/HUALIHUSHAOblog/p/17078325.html优点:可以让应用只关注修改状态的逻辑,清晰代码逻辑