C 将字符类型转换为结构是如何工作的
我有 我的evnt_buff是2。现在,当我输入上述数据时,hci_hdrC 将字符类型转换为结构是如何工作的,c,casting,C,Casting,我有 我的evnt_buff是2。现在,当我输入上述数据时,hci_hdr evnt_buff = sSpiInformation.pRxPacket; data_to_recv = 0; hci_hdr = (hci_hdr_t *)(evnt_buff + sizeof(btspi_hdr)); hci\u hdr->ucType的值为0。这是预期的行为吗 typedef struct _hci_hdr_t { unsigned char ucType; unsig
evnt_buff = sSpiInformation.pRxPacket;
data_to_recv = 0;
hci_hdr = (hci_hdr_t *)(evnt_buff + sizeof(btspi_hdr));
hci\u hdr->ucType
的值为0。这是预期的行为吗
typedef struct _hci_hdr_t
{
unsigned char ucType;
unsigned char ucOpcode;
unsigned char pad[3];
} hci_hdr_t;
我的无符号字符*evnt_buff
;如定义所示。为什么这里要添加sizeof()
上面的代码段是从另一个函数调用的。另一个函数初始化sSpiInformation.pRxPacket
以指向第一个元素为2的缓冲区。这意味着当
typedef struct _btspi_hdr
{
unsigned char cmd;
unsigned short length;
unsigned char pad[2];
}btspi_hdr;
如果执行,则等于2
还有一件事。由于我正在将代码从一个编译器移植到另一个编译器,因此在第一个编译器中,pragma pack(1)用于声明所有结构。但是,因为在我的编译器中,我不知道它的等价物,所以我只是删除了该语句,并在没有任何打包的情况下初始化了该结构。这可能是问题所在吗?这一行
evnt_buff = sSpiInformation.pRxPacket;
表示evnt\U buff所指向的内存包括
btspi\u hdr
hci\u hdr\u t的一个实例
btspi\u hdr
的大小添加到evnt\u buff
中,将表示hci\u hdr\t
的那部分内存的地址分配给hci\u hdr
从这一点上,我得出结论,
hci\u hdr
被声明为hci\u hdr\u t*
,evnt\u buff
是一个指向字符数组的指针,其中第一个元素是2。如果是这样的话,evnt\u buff+sizeof(btspi\u hdr)
有什么意义
无论如何,这个bug可能与结构填充有关。每个编译器都有一个关闭填充的选项,如果不是#pragma pack
,则是其他选项。检查编译器文档
当您有像这样依赖于结构对齐的可疑代码时,还应该添加静态编译时检查以验证是否启用了填充。一种方法是定义一个宏,如果传递的参数不正确,该宏将产生编译器错误。例如:
\define static\u assert(expr){typedef char COMP\u TIME\u assert[(expr)?1:0];}
(如果您有C11编译器,编译器可以使用更好的静态断言)
然后,对于每个结构,键入如下内容:
hci_hdr = (hci_hdr_t *)(evnt_buff + sizeof(btspi_hdr));
我认为,这个问题没有足够的信息,但我肯定没有看到任何东西可以排除
ucType
为零的可能性。你需要解释一下“我的evnt\u buf
is 2”是什么意思。您需要显示evnt\u buff
(或者,等效地,sSpiInformation.pRxPacket
)中的内容;你需要担心在btspi\u hdr
中填充。我已经编辑了这个问题。evnt\u buff是一个字符指针。它能容纳2人。因此,当我输入它并添加大小时,我不应该得到一个2 hci_hdr->uctype甚至连buff
都有一个指向btspi_hdr
的地址。将btspi\u-hdr
的大小添加到even\u-buff
中,此添加的结果指向与even\u-buff
不同的东西,它指向btspi\u-hdr
之后,即指向一个hci\u-hdr\t
,这是有意义的。谢谢
static_assert (sizeof(btspi_hdr) == sizeof(cmd) +
sizeof(length) +
sizeof(pad) );