Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将字符类型转换为结构是如何工作的_C_Casting - Fatal编程技术网

C 将字符类型转换为结构是如何工作的

C 将字符类型转换为结构是如何工作的,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是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;
    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) );