如何对结构进行类型转换

时间:2013-11-21 06:25:15

标签: c casting

我有

 evnt_buff =  sSpiInformation.pRxPacket;
 data_to_recv = 0;
 hci_hdr = (hci_hdr_t *)(evnt_buff + sizeof(btspi_hdr));

我的evnt_buff是2.现在当我将上述数据强制转换为hci_hdr

typedef struct _hci_hdr_t
{
    unsigned char ucType;
    unsigned char ucOpcode;
    unsigned char pad[3];
} hci_hdr_t;

hci_hdr->ucType的值为0.这是预期的行为吗?

typedef struct _btspi_hdr
{
    unsigned char   cmd;
    unsigned short  length;
    unsigned char   pad[2];
}btspi_hdr;

我的unsigned char *evnt_buff;如定义。为什么在这里添加sizeof()确切?

上面的代码从另一个函数调用。另一个函数初始化sSpiInformation.pRxPacket以指向第一个元素为2的缓冲区。这意味着当

 evnt_buff =  sSpiInformation.pRxPacket; 

执行它等于2.

另一件事。由于我将代码从一个编译器移植到另一个编译器,因此在第一个编译器中#pragma pack(1)用于声明所有结构。但是因为在我的编译器中我不知道相当于我只是删除了该语句并初始化了结构而没有任何打包。这可能是问题吗?

2 个答案:

答案 0 :(得分:1)

这一行

hci_hdr = (hci_hdr_t *)(evnt_buff + sizeof(btspi_hdr));

表示evnt_buff指向的内存由

组成
  1. btspi_hdr
  2. 的一个实例
  3. hci_hdr_t
  4. 的一个实例

    所以上面的行是通过添加{{1}的大小来为hci_hdr分配evnt_buff指向的hci_hdr_t所指向的内存部分的地址。到btspi_hdr

    从此我得出结论evnt_buff被声明为hci_hdr

答案 1 :(得分:0)

目前尚不清楚您的意思或尝试实现您说evnt_buff是指向第一个元素为2的字符数组的指针。如果是这样,evnt_buff + sizeof(btspi_hdr)如何做出任何意义?

无论如何,bug可能与struct padding有关。每个编译器都有一个关闭填充的选项,如果不是#pragma pack则其他东西。查看编译器文档。

如果您有这样的可疑代码(依赖于struct alignment),您还应该添加静态编译时检查以验证是否未启用填充。一种方法是定义一个宏,如果传递的参数不正确,则会产生编译器错误。例如:

#define static_assert (expr) {typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0];}

(如果你有一个C11编译器,编译器可以使用更好的static_assert)

然后对于每个结构,输入如下内容:

static_assert (sizeof(btspi_hdr) == sizeof(cmd) +
                                    sizeof(length) +
                                    sizeof(pad) );