Как достать переменную со структуры, которая расположена в void* массиве

Тема в разделе "ESP8266, ESP32", создана пользователем WhiteFox, 7 ноя 2021.

  1. WhiteFox

    WhiteFox Нерд

    Делаю библиотеку GUI листа, пишу на Си. Лист отрисовывается построчно, при этом строки могут быть текстом, редактором текста, ползунком или переключателем.

    Есть структура List_GUI_t, в которой выделено место для указателя элементов листа.
    Элементы листа могут быть разными типами структур, поэтому указатели на них я записываю в void* массив, при этом в первую переменную структуры записан тип структуры.
    Когда структура List_GUI_t полностью готова, я обновляю лист с помощью функции updateList(List_GUI_t *list).
    Задача: в функции нужно достать первую переменную структуры, при этом структура расположена в void* массиве, а массив в структуре List_GUI_t.

    Структура GUI листа:
    Код (C++):
    typedef struct
    {
        Visual_t *visual;
        void *elements; //элементы листа
        uint16_t countElements;
        uint8_t indentY;
        uint8_t triggerStep;
        uint8_t countLineScreen;
        uint16_t cordX;
        uint16_t cordY;
        uint8_t positionCursor;
        uint16_t positionScreen;
    } List_GUI_t;
    Элементы GUI листа(показываю не все):
    Код (C++):
    typedef struct
    {
        typeLine_t typeData; //первая переменная
        char *text;
        char *preText;
    } Text_t;
    Код (C++):
    typedef struct
    {
        typeLine_t typeData; //первая переменная
        uint16_t width;
        uint16_t height;
        uint16_t maxCountPart;
        uint16_t indexPart;
        uint16_t preIndexPart;
    } Slider_t;
    Значения первой переменной:
    Код (C++):
    typedef enum
    {
        TEXT_TYPE, //0
        TEXTEDIT_TYPE, //1
        SLIDER_TYPE, //2
        KEY_TYPE //3
    } typeLine_t;
     
  2. Asper Daffy

    Asper Daffy Иксперд

    преобразовать элемент массива из void * к typeLine_t *

    Только никому не говори, что это я посоветовал. Я говнокодить не советую.

    Мой совет - переделай структуру данных так, чтобы необходимость в говнокоде отпала.
     
    WhiteFox, Andrey12, Vovka и ещё 1-му нравится это.
  3. parovoZZ

    parovoZZ Гуру

    Полностью согласен. Понять, какая структура в массиве и привести ее к соответствующему виду в real-time - это говнокод.
     
  4. WhiteFox

    WhiteFox Нерд

    Даже представить не могу, как по другому сделать, не подскажете? Может уже есть подобные библиотеки для микрух?
    Можно кнш сделать отдельный массив с типами структур, но это как-то банально и не красиво...
    Пока накидывал наброски, заметил, что typedef enum(перечисляемый тип) кушает 4 байта.
    Как изменить прожорливость данного типа до 1 байта?
     
    Последнее редактирование: 8 ноя 2021
  5. Asper Daffy

    Asper Daffy Иксперд

    Если
    то никак, (см. ISO/IEC 9899:201 8 (E) стр. 84, первый абзац снизу: «The expression that defnes the value of an enumeration constant shall be an integer constant expression that has a value representable as an int»).

    Впрочем, раз уж Вам нравится говнокодить, то её можно присваивать байтовому типу, т.е. оригинальный тип не хранить вовсе.
     
    Andrey12 нравится это.
  6. parovoZZ

    parovoZZ Гуру

    А зачем? Памяти не хватает?
     
  7. WhiteFox

    WhiteFox Нерд

    Может не хватить, проект довольно объемный
     
  8. DetSimen

    DetSimen Гуру

    Переходить на enum class.

    enum class ИМЯ_ТИПА: uint8_t {Значение1, Значение2,...ЗначениеN}

    Например

    enum class TAppState:uint8_t {Unknown=0, Normal, Error};
    TAppState AppState = TAppState::Unknown;

    Достоинства: константы внутри enum не видны в глобальном пространстве имён, в отличие от обычного, и занимают столько памяти, сколько отображаемый тип, в данном случае uint8_t, но можно сделать и bool и любой ординарный тип.
    Недостаток: Необходимо использовать квалификатор доступа "::" для констант, что весьма громоздко. В данном примере
    TAppState::Unknown.

    Для получения расширенной информации спроси у гугола что такое "enum class C++" и как с им работать.
     
    WhiteFox, SergeiL и Andrey12 нравится это.
  9. Asper Daffy

    Asper Daffy Иксперд

    ТС сразу сказал, что пишет на Си. Так что - не вариант.

    WhiteFox, кстати, а почему на Си?
     
    Andrey12 и DetSimen нравится это.
  10. SergeiL

    SergeiL Оракул Модератор

    А bool - сколько памяти отъест в этом случае?
     
  11. DetSimen

    DetSimen Гуру

    1 байт

    enum class TActiveLevel: bool {Low=false, High=true};

    переменная такого типа жрёть ровно байт.
     
    SergeiL нравится это.
  12. parovoZZ

    parovoZZ Гуру

    А не проще перечисления объявить через #define?
     
    KindMan нравится это.
  13. WhiteFox

    WhiteFox Нерд

    На Си при разработке ты понимаешь каждый уголок программы от А до Я, а на C++ иногда появляются излишества.
    Да и всегда программу на Си можно перенести на С++.
    Возможно я ошибаюсь, т.к в программировании я год от силы.
     
  14. b707

    b707 Гуру

    ну тогда пишите правильно -
    "...на Си при разработке я понимаю каждый уголок программы..." - то есть дело не в языке :)

    Да и то скорее, только думаете, что понимаете...
     
  15. parovoZZ

    parovoZZ Гуру

    Подождите, мы находимся в ветке ESP. В неё памяти можно засунуть хоть целый вагон и ещё тележку. Неужели есть смысл в ловле блох? Тем паче, как указал выше кот с трибуны, банальный говнокод может занулить все старания.
     
  16. Asper Daffy

    Asper Daffy Иксперд

    Проще, но контроль типов псу под хвост ... говнокод, в общем.
    Я? А кто Вам сказал, что я на С++ чего-то не понимаю? В своей-то собственной программе?
     
    DetSimen нравится это.
  17. WhiteFox

    WhiteFox Нерд

    Любите вы докапываться до каждой мелочи :)
    Как вопрос не задам, постоянно вижу одни и те же лица, что вас подталкивает помогать новичкам?
    Чистый альтрузим или...
     
  18. parovoZZ

    parovoZZ Гуру

    А он и на перечислениях не сильно и работает.
     
  19. DetSimen

    DetSimen Гуру

    а на enum class прекрасно работает, сговнокодить не получится, к подлежащему классу enum константу можно привести только через static_cast, но это только показывает, что ты знаешь, что делаешь.
     
  20. Asper Daffy

    Asper Daffy Иксперд

    Отлично работает, если готовить уметь.