c++ - C++,创建具有可选值的结构
问题描述
我需要创建具有可选值的结构:
typedef struct pkt_header{
unsigned short Packet_Type;
unsigned short Unprotected_Payload_Length;
unsigned short Protected_Payload_Length; // optional (present/not present)
unsigned short Version;
} PKT_HEADER;
当字段不存在时,我如何有时使用pkt_header->Protected_Payload_Length
有时不使用此值?struct
我的第一个想法是在我不使用该字段并使用for 存储我的值时声明unsigned char * Protected_Payload_Length
并传递。NULL
unsigned char*
unsigned short
typedef struct pkt_header{
unsigned short Packet_Type;
unsigned short Unprotected_Payload_Length;
unsigned char * Protected_Payload_Length; // optional
unsigned short Version;
} PKT_HEADER;
我像这样准备我的数据包(并发送这个):
PKT_HEADER header;
header.Packet_Type = 0x0001;
header.Unprotected_Payload_Length = 0x0b00;
header.Protected_Payload_Length = NULL;
header.Version = 0x0000;
我收到回复并这样做:
PKT_HEADER * header= (PKT_HEADER*)recvbuf;
printf("Packet_Type : %04x\n", header->Packet_Type);
printf("Unprotected_Payload_Length : %04x\n", header->Unprotected_Payload_Length);
printf("Version : %04x\n", header->Version);
但在这种情况下,如果我理解正确,unsigned char * Protected_Payload_Length
包含一个长度为 4 个字节的指针,然后header->Protected_Payload_Length
包含4 bytes
但我需要0 byte
,因为在这种精确情况下不存在值/字段。
我是否必须以数据格式声明适当的结构,还是有其他方法可以使用这些结构?
谢谢你的帮助。
解决方案
谨防。结构可以有填充,成员在内存中不一定是相邻的。此外,不允许将某物重新解释为PKT_HEADER
当某物不是PKT_HEADER
对象时。而不是铸造:
PKT_HEADER * header= (PKT_HEADER*)recvbuf;
你可能应该使用memcpy
. 说了这么多,现在到你的实际问题......
如果您依赖结构中具有特定顺序的成员,则不能选择继承。在内存中,基础对象首先出现,然后是派生成员,您不能混合使用。例如
struct foo {
int x;
};
struct bar : foo {
int y;
int z;
};
然后一个bar
对象将在内存中
| x | optional padding | y | optional padding | z | optional padding |
没有简单的获取方法| y | x | z |
。
如果您想要两种不同的类型,最简单的方法是定义两种不同的类型:
struct PKT_HEADER_A {
unsigned short Packet_Type;
unsigned short Unprotected_Payload_Length;
unsigned short Protected_Payload_Length; // present
unsigned short Version;
};
struct PKT_HEADER_B {
unsigned short Packet_Type;
unsigned short Unprotected_Payload_Length;
//unsigned short Protected_Payload_Length; // not present
unsigned short Version;
};
请注意,您通往typedef
结构的方式是 C-ism。在 C++ 中没有必要(也不推荐)。
推荐阅读
- swift - 从字符串中修剪双引号(“)
- android - 如何防止键盘隐藏在视图中
- javascript - PayPal 智能按钮订单 API 忽略 purchase_units 对象中的 notify_url
- wxpython - wx.StaticText 内的文本填充
- python - 如何解释 statsmodels 普通最小二乘模型的结果?
- r - 具有集群数据的固定效应模型
- c# - 如何通过保存在 WPF 应用程序输出目录中的文件对话框使用上传的图像文件?
- r - 如何将均值、中值和标准差合并到数据表的输出中?
- rust - 为什么需要用户输入的代码在 Rust Playground 中不起作用?
- virtualbox - 是否可以使用打包程序 virtualbox-ovf 构建器将临时密钥的公共部分注入 OVA?