错误的数据从void指针复制到struct

时间:2014-05-28 13:21:00

标签: c

好的,所以我已经没有什么可以尝试解决这个问题。

我有一个结构如下:

typedef struct
{
   u8int  NodeType;
   u32int Group;
   u32int Direction;
   u16int ID;

} tsTargetNode;


void vTrackNode(const uint8 *pu8Val, uint8 u8Len, void *pvCbData)
{
   /* Copy data */
   memcpy(pvCbData, pu8Val, u8Len);

   /* Doing this gives the wrong data */
   //tsTargetNode *node = (tsTargetNode *) pvCbData;  

   /* Doing this gives the right data */
   memcpy(&tsTargetNode.NodeType, pvCbData, 1);
   memcpy(&tsTargetNode.Group, pvCbData+1, 4);
   memcpy(&tsTargetNode.Direction, pvCbData+1+4, 4);
   memcpy(&tsTargetNode.ID, pvCbData+1+4+4, 2);
}

例如: 数据通过* pu8Val = 0x AA BB CC DD EE FF 11 22 33 44 55 66 77 88 99 00

使用指针,我检索的数据是:

NodeType  = 0xAA
Group     = 0xFF112233
Direction = 0x44556677
ID        = 0x8899 

但手动memcpy,我检索的数据是正确的

NodeType  = 0xAA  
Group     = 0xBBCCDDEE
Direction = 0xFF112233
ID        = 0x4455

它似乎是第一个尝试将4个字节复制到NodeType中。

我指针副本错了吗?或者这可能是设备/硬件问题?

2 个答案:

答案 0 :(得分:2)

编译器可以在结构的成员之间自由添加填充,这样每个成员都可以与您的平台自然对齐 - 这里看起来像32位。尝试打印sizeof(tsTargetNode),并从初始化的tsTargetNode转储那么多字节,以查看字段的布局方式。

您还没有说过您正在使用的编译器,但是会有一种特定于编译器的方法来禁用您的结构的填充。如果这样做,其内存布局将与缓冲区匹配。

答案 1 :(得分:0)

您需要告诉编译器“打包”结构:

typedef struct __attribute__((__packed__))
{
   u8int  NodeType;
   u32int Group;
   u32int Direction;
   u16int ID;

} tsTargetNode;

https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Type-Attributes.html