简体   繁体   中英

Copy a structure to a member of another structure

I'm on SDCC 3.4 and this is a MIDI project for a musical instrument, and it's a couple of days I'm struggling with this... something that I even find somehow difficult to explain, so here I try to make a better example. Basically, I am scanning for button presses, send MIDI information and lit the LEDs accordingly. What I need is a sort of database holding all the data related to each button, of which a part must be constant (IDs of buttons and LEDs) and a part can be variable because can be varied by the user. At the initialization phase I need to assign the constant part to the structure and leave the variable part unchanged. When the user modifies the function of a button, I need to overwrite the variable part and leave the constant part unchanged.

// 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 },
};

Now, what I need to do is to copy the whole content of cBtnDefinitions[] to Button[]->c . If I do

memcpy(&Button->c, &cBtnDefinitions, sizeof(cBtnDefinitions));

the data is copied in c and v sequentially, not only in the member c.

The rest of the code in the main loop() goes something like this:

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

Of course I may have different types of buttons, so I can use the sButton structure for other purposes, and have them all processed by the same functions.

You always need a loop, as the source cBtnDefinitions is a contiguous memory area whilst the destination consists of 4 separate memory areas.

You can do it with memcpy :

int i;
for (i = 0; i < 4; ++i) {
    memcpy(&Button[i].c, cBtnDefinitions + i, sizeof(sBtnConst));
}

But a simple assignment works as well with GCC:

int i;
for (i = 0; i < 4; ++i) {
    Button[i].c = cBtnDefinitions[i];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM