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

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

简述


大家都知道,在C语音中指针的地位很重要,各种指针,功能很强大!但是用不好,指针也比较容易出问题。


这里介绍的是函数指针的一种应用方法,即使用函数指针来实现消息命令的注册与回调处理。


代码


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

#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);
  //处理数据
}


函数指针定义:

//函数指针
typedef void (*pfunc)(int , const void *, int );


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

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


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

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


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

//处理函数
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  
}


主函数:

#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;
}


编译运行结果

[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
[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


目录
相关文章
|
9小时前
|
C语言
C语言指针与字符串
C语言指针与字符串
|
9小时前
|
存储 C语言
C语言中的指针数组与多重指针
C语言中的指针数组与多重指针
|
12小时前
|
存储 安全 C语言
C语言指针与一维数组的关系深度解析
C语言指针与一维数组的关系深度解析
|
1天前
|
C语言 容器
从C语言到C++_17(list的模拟实现)list不是原生指针的迭代器(下 )
从C语言到C++_17(list的模拟实现)list不是原生指针的迭代器
5 1
|
1天前
|
C语言 计算机视觉
从C语言到C++_17(list的模拟实现)list不是原生指针的迭代器(中)
从C语言到C++_17(list的模拟实现)list不是原生指针的迭代器
9 1
|
1天前
|
存储 算法 编译器
从C语言到C++_17(list的模拟实现)list不是原生指针的迭代器(上)
从C语言到C++_17(list的模拟实现)list不是原生指针的迭代器
8 1
|
1天前
|
C语言
C语言进阶:进阶指针(下)
C语言进阶:进阶指针(下)
|
1天前
|
C语言
C语言进阶:指针的进阶(上)
C语言进阶:指针的进阶(上)
|
1天前
|
C语言
熟悉C语言指针
熟悉C语言指针
|
1天前
|
存储 程序员 C语言
C语言指针
C语言指针