Скопировать структуру в член другой структуры

Я нахожусь на 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];
}
Другие вопросы по тегам