Инитация структуры через чрезмерное использование макроса

StackOverflow https://stackoverflow.com/questions/3259625

Вопрос

У меня есть некоторые структуры для инициализации, что было бы утомительно делать вручную. Я хотел бы создать макрос, который поможет мне с этим ... но я не уверен, что c препроцессор достаточно хорош для этого.

У меня есть структуры, которые представляют меню. Они состоят только из функциональных указателей:

typedef uint8_t (*button_handler) (uint8_t);
typedef void (*pedal_handler) (void);
typedef void (*display_handler) (void);
typedef void (*menu_switch_handler) (void);

#define ON_BUTTON(x) uint8_t menu_frame_##x##_button (uint8_t button)
#define ON_PEDAL(x) void menu_frame_##x##_pedal (void)
#define ON_DISPLAY(x) void menu_frame_##x##_display (void)
#define ON_SWITCH(x) void menu_frame_##x##_switch (void)

typedef struct menu_frame {
   button_handler on_button;
   pedal_handler on_pedal;
   display_handler on_display;
   menu_switch_handler on_switch;
} menu_frame;
.

Это позволяет мне писать функции и отдельные функции как (.c файл):

ON_BUTTON(blah) { ... }
.

и меню как (.h Файл):

ON_BUTTON(blah);
ON_DISPLAY(blah);
menu_frame menu_frame_blah = {
   menu_frame_blah_button,
   NULL,
   menu_frame_blah_display,
   NULL
};
.

Есть ли, как я могу сложить определение меню в один определить? Я мог бы сделать что-то, что расширяет генеракодицетагкод конечно, но есть ли способ:

    .
  • сделать его короче (ноль или некоторое имя)
  • Удалить необходимость генеракодицетагкода от до конструкции

В идеале я хотел бы MENU(blah, menu_frame_blah_button, NULL, menu_frame_blah_display, NULL) для определения обработчиков и самой структуры меню. Например, я не знаю, как предотвратить расширение последнего термина в ON_BUTTON(...);.

или, может быть, я должен подойти к этому из-за другого пути?

Это было полезно?

Решение

Вы не можете выполнить условное расширение макроса в C, так что ваш макрос будет расширен по-разному в зависимости от аргументов, как в: вы не можете использовать #if в рамках определения макроса.

Я думаю, что лучшее, что вы можете получить, будет что-то вроде MENU(blah, ITEM(blah,button), NULL, ITEM(blah,display), NULL), и вам все еще нужен отдельный набор для прототипов из-за отсутствия условного расширения.

Лично я бы написал простой скрипт для создания такого рода кода CoverPlate C.Тот, который бы понял ваш желаемый синтаксис.В Python или что угодно вас лучше всего ...

Другие советы

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

Вы можете запрограммировать условные контуры, конечные петли, аргументы по умолчанию и все такие вещи в препроцессоре в одиночку.Библиотека BOOST имеет реализацию некоторых из них в их препроцессоре.Boost в основном для C ++, но препроцессорные вещи должны в основном работать в C, а также.

По таким методам вы можете написать сложные макросы, но это просто в использовании.Это становится немного проще реализовать при использовании C99 вместо C89 (вы назвали инициализаторы и va_args ), но все же.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top