C语言消息注册派发模式

2 篇文章 0 订阅

如果有这样子的一个场景, 程序收到一个消息id后 需要用很长的if elseif else 或者switch calse来调用对应的函数 ,那可以试试这种注册派发的模式,可以使程序更简洁 可读性更高,我用代码演示一下注册派发的思路,代码不是非常严谨 结构的定义 注册和派发接口 应该独立出来 作为一个工具使用 如果有同学能派上用场, 需要自己再进一步完善下, 好不好用评论区 周知一下哟

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

//定义函数指针类型 参数为可变参数列表
typedef int (*pFunc)(va_list valist);

//定义消息注册结构
struct FuncList{
    int msg_id;            //消息id
    pFunc func;            //消息函数
}

//定义消息id 消息id定义单独一个.h会比较好
#define TEST_MSG 1        //测试消息
#define ADD_MSG 2         //取和函数

//定义消息函数结构列表
int g_func_list_len = 0;
struct FuncList g_func_list[256];

//消息注册函数
void reg_func(int msg_id/*消息id*/, pFunc func/*消息回调函数*/){
    struct FuncList tmp_func;
    tmp_func.msg_id = msg_id;
    tmp_func.func = func;
    g_func_list[g_func_list_len++] = tmp_func;
}

//消息派发函数
void dispatch_func(int msg_id /*消息id*/, ... /*可变参数*/){
    //查找消息id对应的结构key 如果确定消息id比较小 如0-255范围内 则可以g_func_list[msg_id] = func的方式 存储 避免for循环查找 提高效率
    int idx = -1;
    for (int i = 0; i < g_func_list_len; ++i){
        if(g_func_list[i].msg_id == msg_id){
            idx = i;
            break;
        }
    }
    
    //未查找到结果
    if (idx < 0) {
        printf("消息id:%d未注册\n", msg_id);
        return 0;
    }

    //取可变参数列表
    va_list valist;
    /* 注:一定要传入可变参数...的前一个固定参数 va_start, 因为可变参数操作函数va_arg(ptr,type) 是根据提供的参数的内存地址+数据类型字节数偏移读取内存的宏
    */
    va_start(valist, msg_id);
    //传入valist 参数列表 函数里使用va_arg(valist, 数据类型) 依次取出对应参数
    ((pFunc)g_func_list[idx].func)(valist);
    //释放内存
    va_end(valist);
}

//注册和派发接口有了 写个测试用例
//依函数指针类型 定义测试函数
int test_msg_func(va_list valist){
    char * name = va_arg(valist, char *);
    char * test_msg = va_arg(valist, char *);
    printf("name:%s test_msg:%s\n", name, test_msg);
}

//取和函数
int add_func(va_list valist){
    local a = va_arg(valist, int);
    local b = va_arg(valist, int);
    printf("%d + %d = %d\n", a, b, a+b);
}


//主函数
int main(void){
    //注册
    reg(TEST_MSG, test_msg_func);
    reg(ADD_MSG, add_func);
    
    
    //派发
    dispatch_func(TEST_MSG, "小明", "测试消息派发是否正常调用函数");
    dispatch_func(ADD_MSG, 5, 10);

    system("pause");
    return 0;
}




C++游戏服务器开发交流群:136961182,欢迎各位朋友一起交流

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春休夏末

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值