2013-09-06 3 views
3

В моем сетевом приложении в полученном буфере я хочу использовать смещение как указатель на известную структуру. Копирование каждого поля структуры с memcpy() 2 раза (rx/tx) является тяжелым. Я знаю, что мой gcc 4.7.2 (опция: -O3) на cortex-a8, do memcpy (& a, & buff, 4) в 1 команде без знака. Итак, он может получить доступ к unaligned int. Предположим, что у него может быть много структуры или большой структуры. Каков наилучший способ сделать это?Как использовать структуру в неуравновешенном буфере

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

Работает ли это с 'buff' как массив' int '? Добавление 'header_size' приведет к тому, что ваш указатель окажется в неправильном месте. – dasblinkenlight

+3

Убедитесь, что вы понимаете, как работает арифметика указателя. –

+1

Параметры компилятора? Если вы не предприняли действия, чтобы заставить компилятор упаковать эту структуру, он будет использовать естественное выравнивание для полей - это, вероятно, не то, что вы хотите. – marko

ответ

3

поручить GCC использовать выравнивание одного байта для структуры и ее членов, использовать атрибут НКУ packed, показанный на this page. В своем коде, изменения:

struct msg_struct {…} 

к:

struct __attribute__ ((__packed__)) msg_struct {…} 

Вам также необходимо исправить арифметические операции над указателями. Добавление header_size в buff добавляет расстояние 100 int объектов, так как buff является указателем на int. Вероятно, вы должны поддерживать buff как массив unsigned char, а не int.

+0

Да, извините, мой вопрос сосредоточен на том, как access в поле структуры в полученном буфере? например: int valueRcv = msg-> c; и msg-> c = 12; –

+0

@DavidBonnin: ваш код уже содержит такие обращения. Вам нужно исправить арифметику указателя, чтобы 'msg' правильно вычислялся с помощью' unsigned char', а не 'int'. –

Смежные вопросы