gpt4 book ai didi

C libpcap API 将数据包转换为结构(令人困惑)

转载 作者:行者123 更新时间:2023-12-02 02:52:37 24 4
gpt4 key购买 nike

阅读本教程后

(https://www.tcpdump.org/pcap.html)

在最底部,作者将 u_char *packet 指针转换为结构。

这样的类型转换是不是这样的

假设我有这个结构

struct 16bits{ 
int8_t a;
int8_t b;
}

和一个16位的序列

0001 0011 0111 1111

如果我将它转换为 16 位结构,它会看起来像这样吗?

a = 0001 0011
b = 0111 1111

问题是我是否正确理解作者的转换。

我知道结构中的填充,但让我们认为编译器暂时不会添加它

最佳答案

Lets say I have this struct

struct 16bits{ 
int8_t a;
int8_t b;
}

and a 16bit sequence

0001 0011 0111 1111

and if I cast it to 16bits struct it would look like this ?

a = 0001 0011
b = 0111 1111

我假设你的意思是这样的:

// this points at your 16-bit sequence
unsigned char *input_data = ...

struct 16bits *output_data = ( struct 16bits * ) input_data;

uint8_t a_bits = output_data->a;
uint8_t b_bits = output_data->b;

一般来说,不,你不能假设你能做到。一般来说,这将是 a strict aliasing violation和未定义的行为。 “严格的别名”规则基本上是说你不能把内存当作它不是的东西——但除了你每次总是可以访问任何一个 char 之外。 int 不是 float

此外,正如您提到的,结构中的字段之间可以有填充。

不过,在您的具体示例中,它几乎可以肯定在任何平台上“工作”,因为 int8_t 几乎可以肯定是 signed char,所以几乎struct 16bits 中肯定没有填充,并且任何内存都可以作为 char 值访问。

不过,将 char 类型替换为 doubleint64_t 类型,您可能会遇到对齐和填充问题。在某些平台上,这种严格的别名违规会导致代码失败并返回 SIGSEGVSIGBUS

假设 8 位 char 值,所以 int8_t 实际上是一个 char,这是一种完全符合标准的访问所应用的任何数据类型的方式到您的 16 位序列,因为两个 8 位值将是

// assume this points to your 16-bit sequence
unsigned char *input_data = ...

// create a structure that we can actually copy the bits into
struct 16bits output_data;

memcpy( &output_data, input_data, sizeof( output_data ) );

请注意,如果结构包含 char 类型以外的元素,则可能会进行填充。如果您使用 #pragma pack 之类的东西来消除填充,you can wind up with code that doesn't run on some platforms.

您提供的链接中的代码非常猖獗 - 它实际上是未定义的行为。但它“有效”,因为编写最流行的已发布代码的 x86 平台非常、非常、非常宽容未对齐的访问(尽管仍然存在性能损失)。但是这种类型的代码在任何有对齐要求的平台上根本无法正常工作。就Google pragma pack sigbus例如,当在 x86 上运行良好的代码在 ARM 或 SPARC 平台上运行失败时,您会发现许多程序员感到惊讶的例子。

关于C libpcap API 将数据包转换为结构(令人困惑),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51380958/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com