реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Как переписать данные из массива в структуру?
011119xx
сообщение Jul 22 2011, 07:13
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544



Прошу помощи у специалистов в следующем. Часть кода выглядит так:
Код
typedef struct _SETTINGS_DATA
{
     uint8_t                    theme;
     uint8_t                    volume;
     uint16_t                  timing;
} settings_data_t;

typedef settings_data_t *psettings_data_t;

settings_data_t Settings_Data;
uint8_t sFLASH_SPI_Buffer_Rx[512];

void read_settings(void)
{
      ... здесь в буфер sFLASH_SPI_Buffer_Rx читаются данные (уже все работает)...

      ... ЗДЕСЬ НАДО ПЕРЕПИСАТЬ ДАННЫЕ ИЗ sFLASH_SPI_Buffer_Rx В Settings_Data ...

}

void main(void)
{
     ... лишнее опущено ...

     read_settings();

     ... лишнее опущено ...
}


Как это сделать правильно и компактно?
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jul 22 2011, 07:28
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(011119xx @ Jul 22 2011, 10:13) *
Как это сделать правильно и компактно?


В общем случае никак, поскольку нет никакой информации, как расположены данные в буфере приема.
Это, наверное, и заставляет задавать вопросы. Расскажите, как там байтики приняты, сразу же три строчки сами и нарисуются.



--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jul 22 2011, 07:38
Сообщение #3


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



memcpy(sFLASH_SPI_Buffer_Rx, &Settings_Data, sizeof(Settings_Data));
Предварительно обратно - в обратном порядке.
Тогда будет совершенно по барабану размерность, выравнивание и эндианность.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
011119xx
сообщение Jul 22 2011, 07:42
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544



Цитата(Dog Pawlowa @ Jul 22 2011, 13:28) *
... поскольку нет никакой информации, как расположены данные в буфере приема.

Если описать грубо то так:
sFLASH_SPI_Buffer_Rx[0] соответствует theme,
sFLASH_SPI_Buffer_Rx[1] соответствует volume,
sFLASH_SPI_Buffer_Rx[2] соответствует мл. байт timing,
sFLASH_SPI_Buffer_Rx[3] соответствует ст. байт timing.
Go to the top of the page
 
+Quote Post
Danis
сообщение Jul 22 2011, 07:54
Сообщение #5


Twilight Zone
***

Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990



Цитата(011119xx @ Jul 22 2011, 10:13) *
Как это сделать правильно и компактно?


Начнем с того, что за это массив и как он получен?
Если я Вас правильно понял, Вам нужно заполнить экземпляр структуры данными, хранящимися в массиве. Для этого изначально нужно этот массив получить, вычитав экземпляр. Размер массива должен быть как минимум sizeof(settings_data_t) в Вашем случае. Помните, что размер структуры не обязательно равен сумме типов данных в ней описанных.
Так, копирование экземпляра структуры в массив и наоборот будет выглядеть так:
Код
typedef struct _SETTINGS_DATA
{
     unsigned char    theme;
     unsigned char    volume;
     unsigned short    timing;
} settings_data_t;

settings_data_t Settings_Data;

unsigned char Data[4];  // Размер в байтах равен(кратен)  sizeof(Settings_Data)

void f(void)
{
    Settings_Data.theme  = 8;
    Settings_Data.timing = 478;
    Settings_Data.volume = 45;

    memcpy( &Data[0], &Settings_Data,  sizeof(Settings_Data) );  // Из структуры в массив
    memcpy( &Settings_Data, &Data[0], sizeof(Settings_Data) );  // Из массива в структуру

}


--------------------
Magic Friend
Go to the top of the page
 
+Quote Post
011119xx
сообщение Jul 22 2011, 07:56
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544



Цитата(MrYuran @ Jul 22 2011, 13:38) *
memcpy(sFLASH_SPI_Buffer_Rx, &Settings_Data, sizeof(Settings_Data));
Предварительно обратно - в обратном порядке.
Тогда будет совершенно по барабану размерность, выравнивание и эндианность.

Спасибо. Работает превосходно.
Go to the top of the page
 
+Quote Post
Danis
сообщение Jul 22 2011, 07:58
Сообщение #7


Twilight Zone
***

Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990



Цитата(011119xx @ Jul 22 2011, 10:42) *
Если описать грубо то так:
sFLASH_SPI_Buffer_Rx[0] соответствует theme,
sFLASH_SPI_Buffer_Rx[1] соответствует volume,
sFLASH_SPI_Buffer_Rx[2] соответствует мл. байт timing,
sFLASH_SPI_Buffer_Rx[3] соответствует ст. байт timing.


так не надо!


--------------------
Magic Friend
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jul 22 2011, 08:05
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(MrYuran @ Jul 22 2011, 10:38) *
Тогда будет совершенно по барабану размерность, выравнивание и эндианность.

Это если отправитель пользуется структурой того же типа, что не факт.
Иначе бы автор эту структуру отправлял, и скорее всего и принять бы смог.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 22 2011, 09:16
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Danis @ Jul 22 2011, 11:54) *
unsigned char Data[4]; // Размер в байтах равен(кратен) sizeof(Settings_Data)

Тогда почему бы так и не написать прямо в коде вместо комментария? А то потом settings_data_t десять раз поменяется, а четверка будет благополучно забыта.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jul 22 2011, 09:38
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(aaarrr @ Jul 22 2011, 13:16) *
Тогда почему бы так и не написать прямо в коде вместо комментария? А то потом settings_data_t десять раз поменяется, а четверка будет благополучно забыта.


Ну и объявить по простому:

Код
typedef struct _SETTINGS_DATA
{
     unsigned char    theme;
     unsigned char    volume;
     unsigned short    timing;
} settings_data_t;

unsigned char Data[sizeof(settings_data_t)];


И memcpy совсем не нужно:

Код
settings_data_t abc = *(settings_data_t *)Data;


Компилятор сам все скопирует.
Go to the top of the page
 
+Quote Post
Danis
сообщение Jul 22 2011, 09:58
Сообщение #11


Twilight Zone
***

Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990



Цитата(aaarrr @ Jul 22 2011, 13:16) *
а четверка будет благополучно забыта.


Согласен с Вами, просто «разжевал» для ТС, чтоб синтаксисом не перегружать, сам бы вообще через new массив создал.


Цитата(sergeeff @ Jul 22 2011, 13:38) *
Код
settings_data_t abc = *(settings_data_t *)Data;

Компилятор сам все скопирует.


ИМХО тут комментировать надо, что за звездочки и для чего, запутаете ТС. Раз такой вопрос поднялся, тут для ТС пояснять нужно, что есть приведение типов а, что разименование.


--------------------
Magic Friend
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jul 22 2011, 10:00
Сообщение #12


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(Danis @ Jul 22 2011, 13:50) *
Согласен с Вами, просто «разжевал» для ТС, чтоб синтаксисом не перегружать, сам бы вообще через new массив создал.

Вот уж чего точно не следует делать, так это new() без всяких на то причин.
Тем более что в си есть только аллоки. Любой локальный массив создаётся на стеке, а потом гарантированно уничтожается, причём без накладных расходов.
К тому же непонятно, зачем вообще плодить эти массивы.
Почему нельзя воспользоваться исходным буфером.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Danis
сообщение Jul 22 2011, 10:10
Сообщение #13


Twilight Zone
***

Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990



Конечно, можно вообще обойтись без массивов, определил адрес структуры, ее размер и гоняй туда/суда сколько влезет.


--------------------
Magic Friend
Go to the top of the page
 
+Quote Post
Hellper
сообщение Jul 22 2011, 10:51
Сообщение #14


Местный
***

Группа: Участник
Сообщений: 217
Регистрация: 13-08-07
Из: Санкт-Петербург
Пользователь №: 29 745



есть подводный камень связанный с little-endian и big-endian требующий внимания


--------------------
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jul 22 2011, 11:55
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(Hellper @ Jul 22 2011, 14:51) *
есть подводный камень связанный с little-endian и big-endian требующий внимания


По большому счету тут куча подводных камней. В том числе как упакована структура и упакована ли? Да и вся постановка вопроса мутная.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 12:31
Рейтинг@Mail.ru


Страница сгенерированна за 0.01673 секунд с 7
ELECTRONIX ©2004-2016