Скопировать структуру в член другой структуры
Я нахожусь на SDCC 3.4, и это MIDI-проект для музыкального инструмента, и вот уже пару дней я борюсь с этим... с чем-то, что мне даже трудно объяснить, поэтому здесь я пытаюсь сделать лучше пример. По сути, я сканирую нажатия кнопок, отправляю MIDI-информацию и соответствующим образом загораю светодиоды. Что мне нужно, это своего рода база данных, содержащая все данные, относящиеся к каждой кнопке, часть которой должна быть постоянной (идентификаторы кнопок и светодиодов), а часть может быть переменной, потому что может изменяться пользователем. На этапе инициализации мне нужно присвоить постоянную часть структуре и оставить переменную часть без изменений. Когда пользователь изменяет функцию кнопки, мне нужно перезаписать переменную часть и оставить неизменную часть неизменной.
// A structure for the constant part
typedef struct
{
unsigned char btnID; // this holds the n. of input pin for the button
unsigned char ledID; // this holds the n. of output pin for the LED
} sBtnConst;
// A structure for the variable part
typedef struct
{
unsigned char CCnum; // this holds the CC number to send
unsigned char CCval; // this holds the CC value tu send
} sBtnVar;
// A structure containing all data
typedef struct
{
sBtnConst c;
sBtnVar v;
} sButton;
// Declare an array of button structures
// These will contain both the constant and the variable data
sButton Button[4];
// Now initialize a constant structure for the constant part
const sBtnConst cBtnDefinitions[4] =
{
{ 15, 0 },
{ 14, 1 },
{ 10, 8 },
{ 12, 5 },
};
Теперь, что мне нужно сделать, это скопировать весь контент cBtnDefinitions[]
в Button[]->c
, Если я сделаю
memcpy(&Button->c, &cBtnDefinitions, sizeof(cBtnDefinitions));
данные копируются в c и v последовательно, а не только в член c.
Остальная часть кода в основном цикле () выглядит примерно так:
void doButton(sButton *btn, unsigned char value)
{
LitLED(btn->c.ledID, !value);
SendMidiCC(btn->v.CCnum, btn->v.CCval);
}
// This is a callback function called every time a button has been pushed
void aButtonHasBeenPushed(unsigned char ID, unsigned char value)
{
unsigned char i;
for (i=0; i<NUM_OF_BUTTONS; ++i)
if (i == Button[i].c.btnID)
doButton(&Button[i], value);
}
Конечно, у меня могут быть разные типы кнопок, поэтому я могу использовать структуру sButton для других целей и обрабатывать их все с помощью одних и тех же функций.
1 ответ
Вам всегда нужен цикл, как источник cBtnDefinitions
является непрерывной областью памяти, в то время как пункт назначения состоит из 4 отдельных областей памяти.
Вы можете сделать это с memcpy
:
int i;
for (i = 0; i < 4; ++i) {
memcpy(&Button[i].c, cBtnDefinitions + i, sizeof(sBtnConst));
}
Но простое задание работает и с GCC:
int i;
for (i = 0; i < 4; ++i) {
Button[i].c = cBtnDefinitions[i];
}