另一个经常利用函数指针数组的地方是协议的实现。下面以工业中广泛应用的Modbus-RTU的应用层协议为例,说明采用函数指针数组实现的方式。
首先简要介绍Modbus-RTU的应用层协议。图 1‑1是Modbus的数据帧结构。
图 1‑1 Modbus数据帧结构
Modbus的应用层用Function Code(功能码、1字节)来指定相应数据帧的功能,其后所跟的数据也随Function Code的不同而不同,因此对数据帧的处理操作需根据Function Code而做分支处理。这种情形非常适合采用函数指针数组来实现。图 1‑2的表格是Modbus的Function Code定义表。由于Function Code数量较多,非常适合采用函数指针数组。
图 1‑2 Modbus Function Code表
从表中可以看出Function Code并不连续,因此直接将Function Code作为下标定义函数指针数组的方式并不适合,而是应该采用将Function Code和处理函数定义为结构,然后采用结构数组的方式定义:
#pragma pack(1) typedef struct { uint8_t ucAddress; uint8_t ucFuncCode; } modbus_rtu_head_t; #pragma pack() typedef struct { uint8_t ucFuncCode; void (*handler)(uint8_t *pucFrame); } FuncCode_Handler_t; |
typedef enum { READ_COILS = 0x01, READ_DISCRETE_INPUTS = 0x02, READ_HOLDING_REGISTER = 0x03, READ_INPUT_REGISTER = 0x04, WRITE_SINGLE_COIL = 0x05, WRITE_SINGLE_REGISTER = 0x06, READ_EXCEPTION_STATUS = 0x07, DIAGNOSTICS = 0x08, GET_COM_EVENT_COUNTER = 0x0B, GET_COM_EVENT_LOG = 0x0C, WRITE_MULTIPLE_COILS = 0x0F, |