codex10
codex10

Reputation: 105

Wrong data copied to struct from void pointer

Ok so I've run out of things to try and fix this.

I've got a struct as follows:

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);
}

For example: Data passed *pu8Val = 0x AA BB CC DD EE FF 11 22 33 44 55 66 77 88 99 00

using pointer, the data I retrieved is:

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

but manually memcpy, the data I retrieved is correct

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

it seems like the first set it tries to copy 4 bytes into the NodeType.

Am I doing the pointer copy wrong? or could this be a device / HW problem?

Upvotes: 1

Views: 287

Answers (2)

John Zwinck
John Zwinck

Reputation: 249444

You need to tell your compiler to "pack" the struct:

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

Upvotes: 0

Useless
Useless

Reputation: 67782

The compiler is free to add padding between the members of a structure, so that each member is aligned to whatever is natural for your platform - here, it looks like 32 bits. Try printing sizeof(tsTargetNode), and dumping that many bytes from an initialized tsTargetNode to see how the fields are laid out.

You haven't said what compiler you're using, but there will be a compiler-specific way to disable padding for your structure. If you do that, its memory layout will match the buffer.

Upvotes: 2

Related Questions