从结构体中生成16位字
Form 16 bit words from a struct
所以我正在创建一个ICMPv4 echo请求,并决定滚动我自己的结构来保存数据包。为了便于在wireshark中识别数据包,我决定在data字段中添加abcde。
struct icmpPacket{
u_int8_t icmp_type:8, icmp_code:8;
u_int16_t icmp_checksum:16, icmp_id:16, icmp_seqnum:16;
char icmp_data[6]; //cheat a little bit, set the field just large enough to store "abcde";
} __attribute__((aligned (16))) icmppckt; // icmp has an 8 byte header + 6 bytes of data
我遇到的问题是如何使编译器将结构体读取为一系列16位字
符合标准的方法是通过memcpy
:
icmpPacket packet = { /* ... */ };
uint16_t buf[sizeof(icmpPacket) / sizeof(uint16_t)];
memcpy(buf, &packet, sizeof(icmpPacket));
/* Now use buf */
现代编译器足够聪明,可以适当地优化这一点,而无需实际执行函数调用。参见clang和g++的例子)。
一个通用的编译器扩展允许你使用联合,尽管在c++标准下这是未定义的行为:
union packet_view{
icmpPacket packet;
uint16_t buf[sizeof(icmpPacket) / sizeof(uint16_t)];
};
icmpPacket packet = { /* ... */ };
packet_view view;
view.packet = packet;
/* Now read from view.buf. This is technically UB in C++ but most compilers define it. */
使用reinterpret_cast<uint16_t*>(&packet)
或其C等价将打破严格的混叠规则并导致未定义的行为。(基本§3.10。c++标准:
如果程序试图通过该行为不是下列类型之一的全局值定义:
- 对象的动态类型,
- 对象动态类型的cv限定版本,
- 与对象的动态类型相似的类型(定义见4.4),
- 与对象的动态类型对应的有符号或无符号类型的类型,
- 有符号或无符号类型,对应于对象动态类型的cv限定版本,
- 聚合或联合类型,在其元素或非静态数据成员(包括:类的元素或非静态数据成员包含联盟),
- 是对象动态类型的基类类型(可能是cv限定的),
一个char或unsigned char类型。
同样,C11的§6.5/p7说:
对象的存储值只能由左值访问具有下列类型之一的表达式:
- 与对象的有效类型兼容的类型,
- 与对象的有效类型兼容的类型的限定版本,
- 与对象的有效类型相对应的有符号或无符号类型的类型,
- 与对象有效类型的限定版本相对应的有符号或无符号类型的类型,
- 聚合或联合类型,在其成员中包含上述类型之一(递归地包括a子聚合或包含联合),或
- 字符类型。
可以使用16位指针
- 但是你需要添加将对齐到1字节的结构元素!!
-
在c++中你可以这样做:
#pragma pack(1) struct icmpPacket { u_int8_t icmp_type:8, icmp_code:8; u_int16_t icmp_checksum:16, icmp_id:16, icmp_seqnum:16; char icmp_data[6]; //cheat a little bit, set the field just large enough to store "abcde"; } icmppckt; // icmp has an 8 byte header + 6 bytes of data WORD *picmppckt16=(WORD*)((void*)&icmppckt); #pragma pack()
-
将WORD更改为编译器知道的16位数据类型
相关文章:
- 如何通过UDP接收QByteArray并将其解析为位字段结构?
- 如何使用位字段将数据从二进制文件复制到结构中?
- 结构体和类的不同大小(),彼此具有相同的字段类型
- sizeof 函数如何在带和不带位字段的结构上工作?(填充)
- 只写结构体的某些字段
- 在结构中使用位字段并使用C++从内存中读取实例
- MEMCMP以相同(零值)位字段结构返回非零
- 将包含位字段和动态数据的结构复制到 Char 数组缓冲区中
- 无法汇总初始化类型结构的变量,其中包含在类模板中的位字段成员
- 为什么在未由语言本身定义的结构字节中的位字段顺序
- 导致IAR ARM中出现错误的成员结构位字段元素的Initializer列表初始化
- C 如何从UCHAR数组中填充结构的位字段
- 结构中位字段的用是什么
- 包含位字段的结构的大小
- 具有长长位字段的 C++ 结构
- C++ 结构中的位字段声明
- 结构/类位字段打包
- 从结构体中生成16位字
- c++位域结构体大小定义(为什么它被包装得更大?)
- NDK-在C++中创建16位rgb结构