Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how use a structure in a unaligned buffer

In my network app, in the received buffer, I want to use an offset as a pointer to a known struct. Copying every field of the structure with memcpy() 2 times (rx/tx) is heavy. I know that my gcc 4.7.2 (option: -O3) on cortex-a8, do memcpy(&a,&buff,4) in 1 instruction unaligned. So, he can access to unaligned int. Assume that it could have lot of struct, or big struct. What's the best way to do it?

struct __attribute__ ((__packed__)) msg_struct {
  int a;  //0 offset
  char b; //4 offset
  int c;  //5 offset
  int d[100];  //9 offset
}

char buff[1000];// [0]:header_size [1-header_size]:header [header_size+1]msg_struct

func() {
  struct msg_struct *msg;
  recv ((void *)buff, sizeof(buff));
  msg=buff+header_size; // so, it is unaligned.
  ...
    // some work like:
    int valueRcv=msg->c;
  //or modify buff before send 
  msg->c=12;

  send(buff,sizeof(buff));
}
like image 354
David Bonnin Avatar asked Sep 20 '25 09:09

David Bonnin


1 Answers

To instruct GCC to use an alignment of one byte for a structure and its members, use the GCC packed attribute, shown on this page. In your code, change:

struct msg_struct {…}

to:

struct __attribute__ ((__packed__)) msg_struct {…}

You will also need to correct the pointer arithmetic. Adding header_size to buff adds the distance of 100 int objects, because buff is a pointer to int. You should likely maintain buff as an array of unsigned char rather than int.

like image 129
Eric Postpischil Avatar answered Sep 23 '25 00:09

Eric Postpischil