通过xml定义生成代码,支持数组变长数组结构体嵌套等,能满足常用需求 ,项目地址https://bitbucket.org/esrrhs/gencode
生成的例子
#pragma once #include <stdint.h> #define PROTO_MIN(a,b) ((a) < (b) ? (a) : (b)) namespace Protocol { // 消息id enum MsgID { // 请求登录 CS_REQ_LOGIN = 1, // 返回登录 SC_RES_LOGIN = 2, }; // 常量 enum ConstDefine { // 用户名 ACC_LEN = 32, // 角色名 NAME_LEN = 32, // 密码 PWD_LEN = 32, // 密码 ROLE_INFO_NUM = 5, // 好友 FRIEND_LEN = 50, }; // 账号信息 struct AccInfo { // 用户名 char m_Acc[ACC_LEN]; // 钻石 uint32_t m_diamond; int Marshal(char * destbuffer, int size) { int ret = 0; // 用户名 if (ret + (int)sizeof(m_Acc) > size) { return -ret; } strncpy(destbuffer, m_Acc, sizeof(m_Acc)); ret += sizeof(m_Acc); destbuffer += sizeof(m_Acc); // 钻石 if (ret + (int)sizeof(m_diamond) > size) { return -ret; } *(uint32_t*)destbuffer = m_diamond; ret += sizeof(m_diamond); destbuffer += sizeof(m_diamond); return ret; } int Unmarshal(char * srcbuffer, int size) { int ret = 0; // 用户名 if (ret + (int)sizeof(m_Acc) > size) { return -ret; } strncpy(m_Acc, srcbuffer, sizeof(m_Acc)); ret += sizeof(m_Acc); srcbuffer += sizeof(m_Acc); // 钻石 if (ret + (int)sizeof(m_diamond) > size) { return -ret; } m_diamond = *(uint32_t*)srcbuffer; ret += sizeof(m_diamond); srcbuffer += sizeof(m_diamond); return ret; } }; // 好友信息 struct FriendInfo { // 数目 uint8_t m_Num; // 唯一id uint64_t m_Guid[FRIEND_LEN]; int Marshal(char * destbuffer, int size) { int ret = 0; // 数目 if (ret + (int)sizeof(m_Num) > size) { return -ret; } *(uint8_t*)destbuffer = m_Num; ret += sizeof(m_Num); destbuffer += sizeof(m_Num); // 唯一id int copyGuidSize = sizeof(uint64_t) * PROTO_MIN(FRIEND_LEN, m_Num); if (ret + copyGuidSize > size) { return -ret; } if (copyGuidSize > 0) { memcpy(destbuffer, m_Guid, copyGuidSize); } ret += copyGuidSize; destbuffer += copyGuidSize; return ret; } int Unmarshal(char * srcbuffer, int size) { int ret = 0; // 数目 if (ret + (int)sizeof(m_Num) > size) { return -ret; } m_Num = *(uint8_t*)srcbuffer; ret += sizeof(m_Num); srcbuffer += sizeof(m_Num); // 唯一id int copyGuidSize = sizeof(uint64_t) * PROTO_MIN(FRIEND_LEN, m_Num); if (ret + copyGuidSize > size) { return -ret; } if (copyGuidSize > 0) { memcpy(m_Guid, srcbuffer, copyGuidSize); } ret += copyGuidSize; srcbuffer += copyGuidSize; m_Num = PROTO_MIN(m_Num, FRIEND_LEN); return ret; } }; // 玩家信息 struct RoleInfo { // 唯一id uint64_t m_Guid; // 角色名 char m_Name[NAME_LEN]; // 血量 uint32_t m_Hp; // 魔量 uint32_t m_Mp; // x float m_X; // y float m_Y; // 好友信息 FriendInfo m_FriendInfo; int Marshal(char * destbuffer, int size) { int ret = 0; // 唯一id if (ret + (int)sizeof(m_Guid) > size) { return -ret; } *(uint64_t*)destbuffer = m_Guid; ret += sizeof(m_Guid); destbuffer += sizeof(m_Guid); // 角色名 if (ret + (int)sizeof(m_Name) > size) { return -ret; } strncpy(destbuffer, m_Name, sizeof(m_Name)); ret += sizeof(m_Name); destbuffer += sizeof(m_Name); // 血量 if (ret + (int)sizeof(m_Hp) > size) { return -ret; } *(uint32_t*)destbuffer = m_Hp; ret += sizeof(m_Hp); destbuffer += sizeof(m_Hp); // 魔量 if (ret + (int)sizeof(m_Mp) > size) { return -ret; } *(uint32_t*)destbuffer = m_Mp; ret += sizeof(m_Mp); destbuffer += sizeof(m_Mp); // x if (ret + (int)sizeof(m_X) > size) { return -ret; } *(float*)destbuffer = m_X; ret += sizeof(m_X); destbuffer += sizeof(m_X); // y if (ret + (int)sizeof(m_Y) > size) { return -ret; } *(float*)destbuffer = m_Y; ret += sizeof(m_Y); destbuffer += sizeof(m_Y); // 好友信息 int retFriendInfo = m_FriendInfo.Marshal(destbuffer, size - ret); if (retFriendInfo <= 0) { return -ret + retFriendInfo; } ret += retFriendInfo; destbuffer += retFriendInfo; return ret; } int Unmarshal(char * srcbuffer, int size) { int ret = 0; // 唯一id if (ret + (int)sizeof(m_Guid) > size) { return -ret; } m_Guid = *(uint64_t*)srcbuffer; ret += sizeof(m_Guid); srcbuffer += sizeof(m_Guid); // 角色名 if (ret + (int)sizeof(m_Name) > size) { return -ret; } strncpy(m_Name, srcbuffer, sizeof(m_Name)); ret += sizeof(m_Name); srcbuffer += sizeof(m_Name); // 血量 if (ret + (int)sizeof(m_Hp) > size) { return -ret; } m_Hp = *(uint32_t*)srcbuffer; ret += sizeof(m_Hp); srcbuffer += sizeof(m_Hp); // 魔量 if (ret + (int)sizeof(m_Mp) > size) { return -ret; } m_Mp = *(uint32_t*)srcbuffer; ret += sizeof(m_Mp); srcbuffer += sizeof(m_Mp); // x if (ret + (int)sizeof(m_X) > size) { return -ret; } m_X = *(float*)srcbuffer; ret += sizeof(m_X); srcbuffer += sizeof(m_X); // y if (ret + (int)sizeof(m_Y) > size) { return -ret; } m_Y = *(float*)srcbuffer; ret += sizeof(m_Y); srcbuffer += sizeof(m_Y); // 好友信息 int retFriendInfo = m_FriendInfo.Unmarshal(srcbuffer, size - ret); if (retFriendInfo <= 0) { return -ret + retFriendInfo; } ret += retFriendInfo; srcbuffer += retFriendInfo; return ret; } }; // 请求登录 struct CSReqLogin { // 用户名 char m_Acc[ACC_LEN]; // 密码 char m_Pwd[PWD_LEN]; int Marshal(char * destbuffer, int size) { int ret = 0; // 用户名 if (ret + (int)sizeof(m_Acc) > size) { return -ret; } strncpy(destbuffer, m_Acc, sizeof(m_Acc)); ret += sizeof(m_Acc); destbuffer += sizeof(m_Acc); // 密码 if (ret + (int)sizeof(m_Pwd) > size) { return -ret; } strncpy(destbuffer, m_Pwd, sizeof(m_Pwd)); ret += sizeof(m_Pwd); destbuffer += sizeof(m_Pwd); return ret; } int Unmarshal(char * srcbuffer, int size) { int ret = 0; // 用户名 if (ret + (int)sizeof(m_Acc) > size) { return -ret; } strncpy(m_Acc, srcbuffer, sizeof(m_Acc)); ret += sizeof(m_Acc); srcbuffer += sizeof(m_Acc); // 密码 if (ret + (int)sizeof(m_Pwd) > size) { return -ret; } strncpy(m_Pwd, srcbuffer, sizeof(m_Pwd)); ret += sizeof(m_Pwd); srcbuffer += sizeof(m_Pwd); return ret; } }; // 返回登录 struct SCResLogin { // 结果 uint8_t m_Ret; // 账号信息 AccInfo m_AccInfo; // 玩家数目 uint8_t m_RoleInfoNum; // 玩家信息 RoleInfo m_RoleInfo[ROLE_INFO_NUM]; int Marshal(char * destbuffer, int size) { int ret = 0; // 结果 if (ret + (int)sizeof(m_Ret) > size) { return -ret; } *(uint8_t*)destbuffer = m_Ret; ret += sizeof(m_Ret); destbuffer += sizeof(m_Ret); // 账号信息 int retAccInfo = m_AccInfo.Marshal(destbuffer, size - ret); if (retAccInfo <= 0) { return -ret + retAccInfo; } ret += retAccInfo; destbuffer += retAccInfo; // 玩家数目 if (ret + (int)sizeof(m_RoleInfoNum) > size) { return -ret; } *(uint8_t*)destbuffer = m_RoleInfoNum; ret += sizeof(m_RoleInfoNum); destbuffer += sizeof(m_RoleInfoNum); // 玩家信息 for (int i = 0; i < ROLE_INFO_NUM && i < m_RoleInfoNum; i++) { int retRoleInfo = m_RoleInfo[i].Marshal(destbuffer, size - ret); if (retRoleInfo <= 0) { return -ret + retRoleInfo; } ret += retRoleInfo; destbuffer += retRoleInfo; } return ret; } int Unmarshal(char * srcbuffer, int size) { int ret = 0; // 结果 if (ret + (int)sizeof(m_Ret) > size) { return -ret; } m_Ret = *(uint8_t*)srcbuffer; ret += sizeof(m_Ret); srcbuffer += sizeof(m_Ret); // 账号信息 int retAccInfo = m_AccInfo.Unmarshal(srcbuffer, size - ret); if (retAccInfo <= 0) { return -ret + retAccInfo; } ret += retAccInfo; srcbuffer += retAccInfo; // 玩家数目 if (ret + (int)sizeof(m_RoleInfoNum) > size) { return -ret; } m_RoleInfoNum = *(uint8_t*)srcbuffer; ret += sizeof(m_RoleInfoNum); srcbuffer += sizeof(m_RoleInfoNum); // 玩家信息 for (int i = 0; i < ROLE_INFO_NUM && i < m_RoleInfoNum; i++) { int retRoleInfo = m_RoleInfo[i].Unmarshal(srcbuffer, size - ret); if (retRoleInfo <= 0) { return -ret + retRoleInfo; } ret += retRoleInfo; srcbuffer += retRoleInfo; } m_RoleInfoNum = PROTO_MIN(m_RoleInfoNum, ROLE_INFO_NUM); return ret; } }; // 网络头消息 struct NetMsgHead { // 时间戳 uint32_t m_Time; // 序列号 uint32_t m_Index; int Marshal(char * destbuffer, int size) { int ret = 0; // 时间戳 if (ret + (int)sizeof(m_Time) > size) { return -ret; } *(uint32_t*)destbuffer = m_Time; ret += sizeof(m_Time); destbuffer += sizeof(m_Time); // 序列号 if (ret + (int)sizeof(m_Index) > size) { return -ret; } *(uint32_t*)destbuffer = m_Index; ret += sizeof(m_Index); destbuffer += sizeof(m_Index); return ret; } int Unmarshal(char * srcbuffer, int size) { int ret = 0; // 时间戳 if (ret + (int)sizeof(m_Time) > size) { return -ret; } m_Time = *(uint32_t*)srcbuffer; ret += sizeof(m_Time); srcbuffer += sizeof(m_Time); // 序列号 if (ret + (int)sizeof(m_Index) > size) { return -ret; } m_Index = *(uint32_t*)srcbuffer; ret += sizeof(m_Index); srcbuffer += sizeof(m_Index); return ret; } }; // 网络消息内容 struct NetMsgPara { // Type int32_t m_Type; union { // 请求登录 CSReqLogin m_CSReqLogin; // 返回登录 SCResLogin m_SCResLogin; }; int Marshal(char * destbuffer, int size) { int ret = 0; // type if (ret + (int)sizeof(m_Type) > size) { return -ret; } *(int32_t*)destbuffer = m_Type; ret += sizeof(m_Type); destbuffer += sizeof(m_Type); switch (m_Type) { // 请求登录 case CS_REQ_LOGIN: { int retCSReqLogin = m_CSReqLogin.Marshal(destbuffer, size - ret); if (retCSReqLogin <= 0) { return -ret + retCSReqLogin; } ret += retCSReqLogin; destbuffer += retCSReqLogin; } break; // 返回登录 case SC_RES_LOGIN: { int retSCResLogin = m_SCResLogin.Marshal(destbuffer, size - ret); if (retSCResLogin <= 0) { return -ret + retSCResLogin; } ret += retSCResLogin; destbuffer += retSCResLogin; } break; default: return -ret; } return ret; } int Unmarshal(char * srcbuffer, int size) { int ret = 0; // type if (ret + (int)sizeof(m_Type) > size) { return -ret; } m_Type = *(int32_t*)srcbuffer; ret += sizeof(m_Type); srcbuffer += sizeof(m_Type); switch (m_Type) { // 请求登录 case CS_REQ_LOGIN: { int retCSReqLogin = m_CSReqLogin.Unmarshal(srcbuffer, size - ret); if (retCSReqLogin <= 0) { return -ret + retCSReqLogin; } ret += retCSReqLogin; srcbuffer += retCSReqLogin; } break; // 返回登录 case SC_RES_LOGIN: { int retSCResLogin = m_SCResLogin.Unmarshal(srcbuffer, size - ret); if (retSCResLogin <= 0) { return -ret + retSCResLogin; } ret += retSCResLogin; srcbuffer += retSCResLogin; } break; default: return -ret; } return ret; } }; // 网络消息 struct NetMsg { // 网络头消息 NetMsgHead m_NetMsgHead; // 网络消息内容 NetMsgPara m_NetMsgPara; int Marshal(char * destbuffer, int size) { int ret = 0; // 网络头消息 int retNetMsgHead = m_NetMsgHead.Marshal(destbuffer, size - ret); if (retNetMsgHead <= 0) { return -ret + retNetMsgHead; } ret += retNetMsgHead; destbuffer += retNetMsgHead; // 网络消息内容 int retNetMsgPara = m_NetMsgPara.Marshal(destbuffer, size - ret); if (retNetMsgPara <= 0) { return -ret + retNetMsgPara; } ret += retNetMsgPara; destbuffer += retNetMsgPara; return ret; } int Unmarshal(char * srcbuffer, int size) { int ret = 0; // 网络头消息 int retNetMsgHead = m_NetMsgHead.Unmarshal(srcbuffer, size - ret); if (retNetMsgHead <= 0) { return -ret + retNetMsgHead; } ret += retNetMsgHead; srcbuffer += retNetMsgHead; // 网络消息内容 int retNetMsgPara = m_NetMsgPara.Unmarshal(srcbuffer, size - ret); if (retNetMsgPara <= 0) { return -ret + retNetMsgPara; } ret += retNetMsgPara; srcbuffer += retNetMsgPara; return ret; } }; }
xml定义:
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <result> <enum name="MsgID" comment="消息id"> <member name="CS_REQ_LOGIN" type="1" comment="请求登录"/> <member name="SC_RES_LOGIN" type="2" comment="返回登录"/> </enum> <enum name="ConstDefine" comment="常量"> <member name="ACC_LEN" type="32" comment="用户名"/> <member name="NAME_LEN" type="32" comment="角色名"/> <member name="PWD_LEN" type="32" comment="密码"/> <member name="ROLE_INFO_NUM" type="5" comment="密码"/> <member name="FRIEND_LEN" type="50" comment="好友"/> </enum> <struct name="AccInfo" comment="账号信息"> <member name="Acc" type="char" length="ACC_LEN" comment="用户名"/> <member name="diamond" type="uint32_t" comment="钻石"/> </struct> <struct name="FriendInfo" comment="好友信息"> <member name="Num" type="uint8_t" comment="数目"/> <member name="Guid" type="uint64_t" length="FRIEND_LEN" ref="Num" comment="唯一id"/> </struct> <struct name="RoleInfo" comment="玩家信息"> <member name="Guid" type="uint64_t" comment="唯一id"/> <member name="Name" type="char" length="NAME_LEN" comment="角色名"/> <member name="Hp" type="uint32_t" comment="血量"/> <member name="Mp" type="uint32_t" comment="魔量"/> <member name="X" type="float" comment="x"/> <member name="Y" type="float" comment="y"/> <member name="FriendInfo" type="FriendInfo" comment="好友信息"/> </struct> <struct name="CSReqLogin" comment="请求登录"> <member name="Acc" type="char" length="ACC_LEN" comment="用户名"/> <member name="Pwd" type="char" length="PWD_LEN" comment="密码"/> </struct> <struct name="SCResLogin" comment="返回登录"> <member name="Ret" type="uint8_t" comment="结果"/> <member name="AccInfo" type="AccInfo" comment="账号信息"/> <member name="RoleInfoNum" type="uint8_t" comment="玩家数目"/> <member name="RoleInfo" type="RoleInfo" length="ROLE_INFO_NUM" ref="RoleInfoNum" comment="玩家信息"/> </struct> <struct name="NetMsgHead" comment="网络头消息"> <member name="Time" type="uint32_t" comment="时间戳"/> <member name="Index" type="uint32_t" comment="序列号"/> </struct> <struct name="NetMsgPara" comment="网络消息内容" type="union"> <member name="CSReqLogin" type="CSReqLogin" ref="CS_REQ_LOGIN" comment="请求登录"/> <member name="SCResLogin" type="SCResLogin" ref="SC_RES_LOGIN" comment="返回登录"/> </struct> <struct name="NetMsg" comment="网络消息"> <member name="NetMsgHead" type="NetMsgHead" comment="网络头消息"/> <member name="NetMsgPara" type="NetMsgPara" comment="网络消息内容"/> </struct> </result>