前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于C语言的函数指针应用-消息命令处理框架

基于C语言的函数指针应用-消息命令处理框架

作者头像
fensnote
发布2021-05-31 16:05:31
4170
发布2021-05-31 16:05:31
举报
文章被收录于专栏:嵌入式技术笔记

简述

大家都知道,在C语音中指针的地位很重要,各种指针,功能很强大!但是用不好,指针也比较容易出问题。 这里介绍的是函数指针的一种应用方法,即使用函数指针来实现消息命令的注册与回调处理。

代码

测试的处理函数,这里为了测试,都是空函数:

代码语言:javascript
复制
#include <stdio.h>
#include "test_msg_proc.h"


void proc_msg_reg(int cmd, const void *pData, int len)
{
    printf("in proc_msg_reg  , cmd: %d, data: %s, data len: %d\n", cmd, (const char *)pData, len);
    //处理数据
}

void proc_msg_login(int cmd, const void *pData, int len)
{
    printf("in proc_msg_login, cmd: %d, data: %s, data len: %d\n", cmd, (const char *)pData, len);
    //处理数据
}

void proc_msg_test(int cmd, const void *pData, int len)
{
    printf("in proc_msg_test , cmd: %d, data: %s, data len: %d\n", cmd, (const char *)pData, len);
    //处理数据
}

函数指针定义:

代码语言:javascript
复制
//函数指针
typedef void (*pfunc)(int , const void *, int );

消息处理节点信息结构体:

代码语言:javascript
复制
//消息处理节点信息结构体
typedef struct MsgProcNodeInfo
{
    int cmd;          //消息名字
    char name[64];    //用于存储消息名字,方便调试
    pfunc func;   //处理回调函数
}MsgProcNodeInfoSt;

接下来是一个消息信息结构体的数组定义,也就是关键部分,消息命令的注册表:

代码语言:javascript
复制
//消息处理注册表,注册命令字与其对应的处理函数
static  MsgProcNodeInfoSt msgMap[]=
{
    {0, "regCmd",   proc_msg_reg},
    {1, "loginCmd", proc_msg_login},
    {2, "testCmd",  proc_msg_test},
};

主处理函数,用于根据命令字在注册表里查找对应的处理函数,然后回调处理。这里面有个小技巧,如果命令字与数组索引正好是一致的,那可以直接拿命令字作为数组的下表去索引对应的节点调用其函数指针即可。

代码语言:javascript
复制
//处理函数
void proc_msg(int cmd, const void *pData, int len)
{
#if 1
    //处理
    int i = 0; 
    for ( i = 0; i < sizeof(msgMap)/sizeof(MsgProcNodeInfoSt); i++ )
    {
        if ( msgMap[i].cmd != cmd )
            continue;

        if ( msgMap[i].func == NULL )
            continue;

        msgMap[i].func(cmd, pData, len);
    }


#else     
    //如果命令字正好与数组索引相同,也可以这样取巧,直接拿命令字作为索引用
    if ( cmd >= sizeof(msgMap)/sizeof(MsgProcNodeInfoSt) ) //越界判断
        return;

    msgMap[cmd].func(cmd, pData, len);
#endif    
}

主函数:

代码语言:javascript
复制
#include <stdio.h>
#include "test_msg_proc.h"

int main(int argc, char **argv)
{
    proc_msg(0, "注册", sizeof("注册"));
    proc_msg(1, "登录", sizeof("登录"));
    proc_msg(2, "测试", sizeof("测试"));

    return 0;
}

编译运行结果

编译:

代码语言:javascript
复制
[fens@fens app/test_func_point]$make 
gcc -Wall  -I. -c main.c -o main.o 
gcc -Wall  -I. -c test_msg_proc.c -o test_msg_proc.o 
gcc ./main.o ./test_msg_proc.o -o test -Wall  -I. -lpthread
strip test

运行:

代码语言:javascript
复制
[fens@fens app/test_func_point]$./test
in proc_msg_reg  , cmd: 0, data: 注册, data len: 7
in proc_msg_login, cmd: 1, data: 登录, data len: 7
in proc_msg_test , cmd: 2, data: 测试, data len: 7

从上面的打印可以看出,命令字处理的时候都对应到了注册的回调函数。

在实际用时,数据的内容可以是十六进制数据,命令字也可以改为字符串格式。

源代码码云地址:

https://gitee.com/fensnote/demo_code/tree/master/c/test_func_point

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 嵌入式技术笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简述
  • 代码
  • 编译运行结果
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档