C风格的结构体#
基本信息#
起草日期: 2022-06-24
设计人员: wendal
动机#
处理结构化数据, 使用pack库不够直观, zbuff适合逐字节出来
c层处理table数据相当麻烦, 很多配置信息又需要table来传
设计思路和边界#
支持基础类型, 不支持嵌套类型, 不支持uion
支持定长数据, 仅支持一级指针
使用场景#
modbus 合成与解析#
主机发送: 01 06 01 05 01 90 99 CB
从机回复: 01 06 01 05 01 90 99 CB
C结构体声明如下
typedef struct modbus {
uint8_t addr;
uint8_t func;
uint16_t regaddr;
uint16_t data;
uint16_t crc;
} modbus_t;
设想的lua代码, 用法A
modbus_t = zstruct.define([[
typedef struct modbus {
uint8_t addr;
uint8_t func;
uint16_t regaddr;
uint16_t data;
uint16_t crc;
} modbus_t;
]])
local modbus = modbus_t:new()
modbus:addr = 0x01
modbus:func = 0x06
modbus:regaddr = 0x0105
modbus:data = 0x0190
modbus:crc = crypto.crc_modbus(modbus)
uart.write(1, zstruct.data(modbus))
local data = uart.read(1, zstruct.sizeof(modbus_t))
modbus_slave = modbus_t:wrap(data)
log.info("modbus", "addr", modbus_slave:addr)
log.info("modbus", "func", modbus_slave:func)
log.info("modbus", "regaddr", modbus_slave:regaddr)
log.info("modbus", "data", modbus_slave:data)
设想的lua代码, 用法B
-- define只需要{ } 之间的数据, 其他部分可以省略
modbus_t = zstruct.define([[
uint8_t addr;
uint8_t func;
uint16_t regaddr;
uint16_t data;
uint16_t crc;
]])
local modbus = modbus_t:new({
addr = 0x01,
func = 0x06,
regaddr = 0x0105,
data = 0x0190
})
modbus:crc = crypto.crc_modbus(modbus)
uart.write(1, zstruct.data(modbus))
local data = uart.read(1, zstruct.sizeof(modbus_t))
modbus_slave = modbus_t:wrap(data)
log.info("modbus", modbus_slave:JSON()) -- 输出JSON格式,方便查看
设想代码C, 这个是方便C层的实现, 用户层依然为table
int luat_struct_map(lua_State *L, int index, char* buff, const char* Define);
modbus_t modbus = {0};
// table是第一个参数, 然后所传Define为modbus_t的文本形式.
int ret = luat_struct_map(L, 1, &modbus, Define);
拟支持的数据类型#
注: _t
后缀可选.
// 有符号类
char
int8_t
int16_t
int32_t
int // 等价于int32
float
// 无符号类
uint8_t
uint16_t
uint32_t
// 指针类
char*
// 数组, 固定长度, 可以是非指针类的基础类型
char[8]
扩展支持#
支持默认值
uint8 addr = 0;
支持位域
uint8 addr : 4;