Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Преобразование структуры в массив и обратно
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
smk
Есть функция для подсчета CRC. Она работает с массивом. Мне же нужно чтобы она считала CRC структуры. Правильней будет сказать, что в пакете 16 байт, последний из них и есть CRC. Его нужно считать перед отправкой пакета и проверять при получении.
Функция:
Код
unsigned char Crc8(unsigned char *buf, unsigned char len)
{
unsigned char crc = 0xFF;
while (len--) crc = Crc8Table[crc ^ *buf++];
return crc;
}


Структура:
Код
struct dataexchange_t      
{
   uchar b1;        
   uchar b2;        
   uchar b3;        
   uchar b4;        
   uchar b5;        
   uchar b6;
   uchar b7;
   uchar b8;
   uchar b9;
   uchar b10;
   uchar b11;
   uchar b12;
   uchar b13;
   uchar b14;
   uchar b15;
   uchar b16;
};


Как проще преобразовать структуру в массив (с ним удобней) ?
GetSmart
Воспользуйтесь юнионом (union). Первое поле будет структурой с любой структурой sm.gif А второе поле будет массивом, который будет нах-ся прямо поверх структуры на этих же адресах. Длины обоих переменных могут совпадать, а могут и отличаться. Общий размер будет равен максимальному.
smk
Цитата(GetSmart @ Dec 10 2011, 10:42) *
Воспользуйтесь юнионом (union). Первое поле будет структурой с любой структурой sm.gif А второе поле будет массивом, который будет нах-ся прямо поверх структуры на этих же адресах. Длины обоих переменных могут совпадать, а могут и отличаться. Общий размер будет равен максимальному.

Не совсем понятно. Может проще переписывать одно в другое и обратно?
Сергей Борщ
QUOTE (smk @ Dec 10 2011, 09:58) *
Есть функция для подсчета CRC. Она работает с массивом. Мне же нужно чтобы она считала CRC структуры.


CODE
unsigned char Crc8(void const *pSrc, unsigned char len)
{
unsigned char const * buf = (unsigned char const *)pSrc;
unsigned char crc = 0xFF;
while (len--) crc = Crc8Table[crc ^ *buf++];
return crc;
}

uint8_t test (dataexchange_t Test_data)
{
  return Crc8(&Test_data, sizeof(Test_data));
}
smk
Есть ли способ написать компактней и красивей вот это:
Код
      buf_rx[0] = pdata.b1;
      buf_rx[1] = pdata.b2;
      buf_rx[2] = pdata.b3;
      buf_rx[3] = pdata.b4;
      buf_rx[4] = pdata.b5;
      buf_rx[5] = pdata.b6;
      buf_rx[6] = pdata.b7;
      buf_rx[7] = pdata.b8;
      buf_rx[8] = pdata.b9;
      buf_rx[9] = pdata.b10;
      buf_rx[10] = pdata.b11;
      buf_rx[11] = pdata.b12;
      buf_rx[12] = pdata.b13;
      buf_rx[13] = pdata.b14;
      buf_rx[14] = pdata.b15;
      buf_rx[15] = pdata.b16;

GetSmart
Цитата(smk @ Dec 10 2011, 15:46) *
Есть ли способ написать компактней и красивей вот это:
Код
      buf_rx[0] = pdata.b1;
...
      buf_rx[15] = pdata.b16;

Код
memcpy(buf_rx,pdata,sizeof(pdata));


Цитата(smk @ Dec 10 2011, 15:27) *
Не совсем понятно. Может проще переписывать одно в другое и обратно?

Юнион не тратит процессорное время когда "так" преобразовывает переменные.
dxp
Цитата(GetSmart @ Dec 10 2011, 15:42) *
Воспользуйтесь юнионом (union).

Только такой подход таит неприятности из-за паддинга на платформах, где есть выравнивание. Чтобы не налетать на подводные грабли, надо в структуре руками вставлять пустые поля и инициализировать их определёнными значениями, чтобы физический sizeof структуры был равен sizeof массива. Либо использовать пакованные структуры, но это непереносимость и оверхед по производительности в размеру кода.
GetSmart
Цитата(dxp @ Dec 10 2011, 19:14) *
Только такой подход таит неприятности из-за паддинга на платформах, где есть выравнивание.

ТС-у желательно знать этот вариант. Чтобы делать осознанный выбор.
Да, есть негативные фичи у метода.
Sirko
Цитата
неприятности из-за паддинга на платформах, где есть выравнивание
Это точно, - проходили между писюком и AVRом.

На счет
Цитата
Как проще преобразовать структуру в массив
не вижу смысла что-то во что-то преобразовывать.

Нужно создать указатель на структуру, например так:

unsigned char *pDataArray = (unsigned char*) &mySruct;
и использовать для подсчета его так, как еслибы Вы использовали массив.
sigmaN
Цитата
Нужно создать указатель на структуру, например так:

unsigned char *pDataArray = (unsigned char*) &mySruct;
и использовать для подсчета его так, как еслибы Вы использовали массив.
Но ведь в таком случае всё равно есть риск наткнуться на неприятности из-за паддинга на платформах, где есть выравнивание.
dxp
QUOTE (sigmaN @ Dec 19 2011, 04:02) *
Но ведь в таком случае всё равно есть риск наткнуться на неприятности из-за паддинга на платформах, где есть выравнивание.

Это можно обойти, если вставлять в структуру паддинг руками, исходя из выравнивания по адресам, кратным 4 (как правило этого должно хватить). Но неудобно, конечно, это делать руками, и ошибки будут регулярно возникать.
sigmaN
В общем самый портабельный и безглючный способ это
Код
buf_rx[0] = pdata.b1;
      buf_rx[1] = pdata.b2;
      buf_rx[2] = pdata.b3;
      buf_rx[3] = pdata.b4;
      buf_rx[4] = pdata.b5;
      buf_rx[5] = pdata.b6;
      buf_rx[6] = pdata.b7;
      buf_rx[7] = pdata.b8;
      buf_rx[8] = pdata.b9;
      buf_rx[9] = pdata.b10;
      buf_rx[10] = pdata.b11;
      buf_rx[11] = pdata.b12;
      buf_rx[12] = pdata.b13;
      buf_rx[13] = pdata.b14;
      buf_rx[14] = pdata.b15;
      buf_rx[15] = pdata.b16;
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.