Как вытащить массив, вложенный в структуру?

Есть вот такая готовая структура:

typedef struct {
    int cmd;                /*<! The specific LCD command */
    const void *data;       /*<! Buffer that holds the command specific data */
    size_t data_bytes;      /*<! Size of `data` in memory, in bytes */
    unsigned int delay_ms;  /*<! Delay in milliseconds after this command */
} st7701_lcd_init_cmd_t;

static const init_cmd[] = {
    {0xFF, (uint8_t []){0x77, 0x01, 0x00, 0x00, 0x13}, 5, 0},
    {0xEF, (uint8_t []){0x08}, 1, 0},
    {0xFF, (uint8_t []){0x77, 0x01, 0x00, 0x00, 0x10}, 5, 0},
    {0xC0, (uint8_t []){0x2c, 0x00}, 2, 0},
    {0xC1, (uint8_t []){0x10, 0x0C}, 2, 0},
    {0xC2, (uint8_t []){0x21, 0x0A}, 2, 0},
};

Подскажите, как правильно объявить эту структуру в ардуиновском C++ и получить доступ к элементам массива data для перебора элементов? Дело в том, что в SDK для китайских контроллеров типа BL616 на C это все работает прекрасно через передачу указателя в функцию и отсчет указанного числа элементов в функции. Вот так: my_func((void *)init_cmd[i].data, init_cmd[i].data_bytes). Но в arduino ide как ни старался, получаю только значение адреса в памяти и сообщение “is not pointer-to-object” при попытке получить по нему значение, или не выровненные значения, которые то совпадают, то не совпадают с фактическими элементами массива. Что обидно, всякие ардуиновские библиотеки портируются в китайцев на ура, а в обратную сторону уперся в какой-то тупик…

И как вы ни старались?
Wiring - это тот же C++.

Так покажите на как Вы ни старались. Мож чего подскажем.

Причём именно код покажите, т.к. Ваши объяснения “к коду не пришьёшь”. Например:

скорее напоминает выписку из истории болезни, а не описание кода.

Я знаю, что Wiring = C++. Я знаю, как решить задачу на С, и не понимаю, почему это решение не работает на C++. Поэтому я задаю в песочнице конкретный вопрос: как получить на C++ доступ к элементам массива, вложенного в структуру?

Через указатель и смещение, как и везде.

Не совсем понял про “покажите код” - мне сюда скопировать пример LHAL драйвера дисплея из Bouffalo Lab SDK?)) Там инициализация дисплея размазана тонким слоем по трем тысячам строк кода)) Если коротко, там сделано так:
функция выгрузки в дисплей

void my_func(uint32_t *para, size_t para_num)
{
     bflb_spi_poll_exchange(spi_hd, para, NULL, para_num);
}

и вызов этой функции внутри цикла по i:
my_func((void *)init_cmd[i].data, init_cmd[i].data_bytes);

В BFLB SDK это работает. В Arduino IDE компилятор ругается на para “not pointer-to-object”.

Наверное вы представляете себе, что мы тут такие сидим погруженные в эти китайские драйвера, сдк и точно знаем где ваша функция и в каком окружении вызывается.

Это не так.
Напишите мелкий скетч с вашей инициализированной структурой, циклом и передачей в функцию по указателю. Сразу поймете, что все как в обычном C++.

Вот это в C работает?? Без типа? Не надо заливать.


Фантастика

BFLB2

BFLB3

Может и фантастика. Но у китайцев работает. Это скриншоты рабочего HAL ST7735.

Сорян, стирал длинное имя, и случайно стер тип. В оригинале конечно же тип есть:

static const st7701_lcd_init_cmd_t vendor_specific_init_default[] = {
    {0xFF, (uint8_t []){0x77, 0x01, 0x00, 0x00, 0x13}, 5, 0},
    {0xEF, (uint8_t []){0x08}, 1, 0},
    {0xFF, (uint8_t []){0x77, 0x01, 0x00, 0x00, 0x10}, 5, 0},
    {0xC0, (uint8_t []){0x2c, 0x00}, 2, 0},
    {0xC1, (uint8_t []){0x10, 0x0C}, 2, 0},
    {0xC2, (uint8_t []){0x21, 0x0A}, 2, 0},
    {0xCC, (uint8_t []){0x10}, 1, 0},

Пришлите output компилятора, где он ругается. Я два раза прочитал, ничего не понял :expressionless:

Попробуйте void *data заменить на массив фиксированной длины, ну, там, 5 байт.

const unsigned char data[5];

Инициализация init_cmd будет красивее выглядеть. Что у вас с типами такой огород? В структуре - void *, в инициализаторе - uint8_t *.

Попробуйте ваши строчки объявить отдельно, скажем, так:

static const unsigned char string1[] = { 0x77, 0x01, 0x00, 0x00, 0x13};
static const unsigned char string2[] = {0x08};
  ...

а структуру проинициализировать уже этими строчками:

static const st7701_lcd_init_cmd_t init_cmd[] ={
          {0xff, (const void *)string1, ..., ...},
           {0xef, (const void *)string2, ..., ...},
...
};```

Попробуйте ваши строчки объявить отдельно, скажем, так:

Навскидку, ожидается 5-6 дисплеев, по 80-120 строк для каждого. Хотелось бы максимально скопипастить иниты у китайцев без ручной работы.

Вот такой у меня получился тестовый код (структура урезана для наглядности):

typedef struct {
    int cmd;
    const uint8_t *data;
    size_t data_bytes;
    unsigned int delay_ms;
} st7701_lcd_init_cmd_t;

static const st7701_lcd_init_cmd_t init_cmd[] = {
    {0xFF, (uint8_t []){0x77, 0x01, 0x00, 0x00, 0x13}, 5, 0},
    {0xEF, (uint8_t []){0x08}, 1, 0},
    {0xFF, (uint8_t []){0x77, 0x01, 0x00, 0x00, 0x10}, 5, 0},
    {0xC0, (uint8_t []){0x2c, 0x00}, 2, 0},
    {0xC1, (uint8_t []){0x10, 0x0C}, 2, 0},
    {0xC2, (uint8_t []){0x21, 0x0A}, 2, 0},
};

void setup() {
  Serial.begin(9600);

  my_func((uint32_t *)(init_cmd[0].data), init_cmd[0].data_bytes);

}

void loop() {

}

void my_func(uint32_t *para, size_t para_num) {
  uint8_t regval;
  for(uint8_t i=0; i<para_num; i++) {
    regval = *(uint8_t *)para;
    Serial.print(regval, HEX);
    Serial.println("\r");
    para++;
  }
}

Он работает, но выводит сначала первый элемент массива, а потом остальные, но в обратном порядке. Например, для нулевой строки структуры получается:

77
13
0
0
1

У вас para - указатель на uint32.
Инкремент в 34 строчке прибавит сразу 4 байта.
Измените функцию my_func так, чтобы первый параметр был uint8_t *

Вы за границу массива вылезли.

А что, можно в структурах явно не указывать размерность массива и потом не иметь с этого больной головы ?

Что-то типа такого. Надеюсь, скомпилируется.

void my_func(uint8_t *para, size_t para_num) {
  for(uint8_t i=0; i<para_num; i++ , para++)
    Serial.printf("%02X\r",*para);
}

Это повсеместно встречается в свежих примерах из пакетов поставки SDK, типа Buffalo и Seeed и прекрасно работает. Я просто тупо скопировал их официальный код.

Нетъ…

Compilation error: cannot convert ‘uint32_t* {aka long unsigned int*}’ to ‘uint8_t* {aka unsigned char*}’ for argument ‘1’ to ‘void my_func(uint8_t*, size_t)’

я уже пробовал, не помогло…

Похоже, что Вы действительно

Давайте я попробую объяснить, понятнее.

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

До тех пор пока это не будет, здесь будет обсуждение программы без кода (это что-то вроде полового сношения без партнёрши). Господь как известно не очень приветствует мастурбацию

«Зло было пред очами Господа то, что он делал; и Он умертвил и его» (Быт. 38:10)

Поэтому лично я в этом участвовать не буду (остальные как хотят)

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