C++ 变量类数组
我有以下数据包布局:C++ 变量类数组,c++,C++,我有以下数据包布局: struct PacketLayout { int GateCode; BYTE StringLen; char String[StringLen]; BYTE ServerStatus; BYTE ServerStorage; BYTE ServerNumber; } 课程内容如下: class ServerInfo { short PacketSize; //Size of the whole packet BYTE TotalSe
struct PacketLayout
{
int GateCode;
BYTE StringLen;
char String[StringLen];
BYTE ServerStatus;
BYTE ServerStorage;
BYTE ServerNumber;
}
课程内容如下:
class ServerInfo
{
short PacketSize; //Size of the whole packet
BYTE TotalServers; //total of PacketLayout structs
PacketLayout Server[TotalServers];
int GlobalSecCode;
short EncryptedPacketSize; //Same as the first member, just xored
}
因此,我的问题是在类或结构中创建一个大小可变的数组,其大小取决于字节StringLen(对于结构)和字节TotalServers(对于类)所指向的最后一个成员
我不知道这个问题的解决方案是什么,也许可以实现一个模板?如果是这样,我可以看到一个示例(我还不熟悉模板)并且我想引用我的成员名称,而不需要自己计算指针位置(就像我现在做的那样)
谢谢。可以使用模板执行此操作,例如:
template <int StringSize>
struct PacketLayout
{
int GateCode;
BYTE StringLen;
char String[StringSize];
BYTE ServerStatus;
BYTE ServerStorage;
BYTE ServerNumber;
};
或者:
struct PacketLayout
{
int GateCode;
BYTE StringLen;
BYTE ServerStatus;
BYTE ServerStorage;
BYTE ServerNumber;
char *String;
};
并在读取过程中分配/设置String
就我个人而言,我会跳过所有这些杂乱无章的低级细节,用一些类似于为你做工作的东西,让你自由地专注于更重要、更高层次的事情,为你的项目增加价值
有时也会使用一种常见但肮脏的伎俩:
struct PacketLayout
{
int GateCode;
BYTE StringLen;
BYTE ServerStatus;
BYTE ServerStorage;
BYTE ServerNumber;
char String[1];
};
在这种情况下,人们将末尾变量部分的大小定义为1,然后故意分配比结构所需的内存更多的内存,这样他们就可以写过结构的末尾。这是邪恶的,但不推荐使用。使用模板绝对是一种方法:
template <size_t TotalServers>
class ServerInfo
{
PacketLayout Server[TotalServers];
int GlobalSecCode;
};
模板
类服务器信息
{
PacketLayout服务器[TotalServers];
int-GlobalSecCode;
};
这有一个缺点:没有一个代码> Server信息<代码>可分配给另一个,所以可能使用一个<代码>:ST::vector < /C>是很重要的,如果这对你来说意义重大。
< P> C++中没有一个好的方法来实现这一点。 以下是如何在PacketLayout中创建可变大小数组:struct PacketLayout
{
int GateCode;
BYTE StringLen;
BYTE ServerStatus;
BYTE ServerStorage;
BYTE ServerNumber;
char String[1];
}
然后分配一个实例:
PacketLayout* createPacketLayout(BYTE stringLen)
{
PacketLayout* packetLayout = (PacketLayout*)new char[sizeof(PacketLayout) - 1 + stringLen];
packetLayout->StringLen = stringLen;
return packetLayout;
}
在此情况下,ServFielo可以保存指针数组。
我不确定你的意思是:“我想引用我的成员名字而不用自己计算指针位置”,在C++中没有解决这个问题的方法。除非您在编译时知道ServerInfo.TotalServer和PacketLayout.StringLen的值,否则模板不会有帮助。你只需要自己计算偏移量。Flexo现在我自己计算字符串成员的指针位置,因为没有办法让它成为编译时。你确定@jahhaj吗?我觉得这很令人不安。。。除了像以前的ASM那样自己计算偏移量之外,难道不是更高级的方法吗?lol@jahhaj-只需编写一个函数,将字节从线路上拉入,然后将它们放在合理设计的结构的正确位置。数据包和结构之间的1:1映射并不总是可行的方法。初始化结构如何,方法是一样的?同样正如Flexo的回答所指出的,我需要通过StringLen成员获得字符串大小,所以您可以设置一个更完整的示例吗?谢谢。那上课呢?这个类还有一个PacketLayout结构的变量数组,我不知道PacketLayout在编译时的大小。字符串的大小由StringLen成员指出。@ffenix是否可以使用std::string
而不是char
数组?@ffenix:这是您的问题,除非您知道编译时这些大小模板对您没有帮助。查看Flexo如何编写PacketLayour pkt代码>,100必须是一个编译时常量。@juanchopanza-这似乎不是一个选项-它看起来像是一个POD,即可以直接写入文件/流。@jahhaj:我在服务器上接收的大多数数据包的大小在编译时是不确定的,所以我想用一种合理的高级语法来分析它们?
struct PacketLayout
{
int GateCode;
BYTE StringLen;
BYTE ServerStatus;
BYTE ServerStorage;
BYTE ServerNumber;
char String[1];
}
PacketLayout* createPacketLayout(BYTE stringLen)
{
PacketLayout* packetLayout = (PacketLayout*)new char[sizeof(PacketLayout) - 1 + stringLen];
packetLayout->StringLen = stringLen;
return packetLayout;
}