Array of structs with object references

Description

I want to create an array of structs with several items, including a reference to a ui object.
Without the ui object the construction works. With the object it doesn’t (likely a memory allocation issue).

Code to reproduce

struct Button {
  char name[15];
  bool zigbee;
  char mqtt[20];
  lv_obj_t* button;
  int  brightness;
  int8_t red;
  int8_t green;
  int8_t blue;
  bool dimming;
  bool color;
  bool color_temp;
};

#define MQTTendpoints 2

Button Buttons[MQTTendpoints] = {
  { "Kitchen",   false, "lamp_kitchen", ui_ButtonKitchen,      50, 0,0,0,     true,  false, false },
  { "Bedroom", true,  "lamp_bedroom",   ui_ButtonBedroom,     50, 10,50,100, true,  true,  true  },
};

Try &ui_But…

That doesn’t compile:
cannot convert 'lv_obj_t**' {aka '_lv_obj_t**'} to 'lv_obj_t*' {aka '_lv_obj_t*'} in initialization

And how error is in your first use??

Try

lv_obj_t *button;

This compiles fine, as does my code.

But I found the issue: I had two different definitions of the struct in use.
So my code was actually correct.
Thanks anyway for your help!

You could have an issue with the char arrays in the structure. There is no way to know the length of those fields so they should be null terminated.

Button Buttons[MQTTendpoints] = {
  { "Kitchen\0",   false, "lamp_kitchen\0", ui_ButtonKitchen, 50, 0, 0, 0, true, false, false },
  { "Bedroom\0", true,  "lamp_bedroom\0",   ui_ButtonBedroom, 50, 10, 50, 100, true, true, true },
};

while it might be working now but you could end up with an issue in the future. you should null terminate the strings. you may have to increase the array length by one in order to be able to do that. if the longest string is 20 then you would set the array to have a length of 21.

It seems like your ui_Button uninitilized during compile time. But lvgl initilize objects in runtime. So your lv_obj_t* button; at best case scenario initilized as NULL, at worst - with random number. Try to equate button fields after relevant call of lv_obj_create()

Yes, I found that the pointers only get initialized during runtime.
I will probably use a double-pointer construction.

Thanks for all the advise.

Just add something like this in place where you create btn’s

Button Buttons[MQTTendpoints] = {
  { "Kitchen",   false, "lamp_kitchen",  NULL,      50, 0,0,0,     true,  false, false },
  { "Bedroom", true,  "lamp_bedroom",   NULL,     50, 10,50,100, true,  true,  true  },
};
....
ui_ButtonKitchen = lv_btn_create(parent);
Buttons[0].button = ui_ButtonKitchen;

and in place where you use .button field add NULL-checking

if(Buttons[0].button  != NULL)
{
.... your actions ....
}