Pregunta

Tengo que inicializar algunas estructuras, lo cual sería tedioso si lo hiciera manualmente.Me gustaría crear una macro que me ayude con esto...pero no estoy seguro de C El preprocesador es lo suficientemente bueno para esto.

Tengo estructuras que representan menús.Consisten únicamente en punteros de función:

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;

Eso me permite escribir las funciones y funciones separadas como (archivo .c):

ON_BUTTON(blah) { ... }

y menús como (archivo .h):

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

¿Hay alguna manera de poder plegar la definición del menú en una sola definición?Podría hacer algo que se expanda. MENU(blah, menu_frame_blah_button, NULL, menu_frame_blah_display, NULL) por supuesto, pero ¿hay alguna manera de:

  • hazlo más corto (NULL o algún nombre)
  • eliminar la necesidad de ON_BUTTON(...); desde antes de la estructura

Idealmente me gustaría MENU(blah, button, NULL, display, NULL) para definir los controladores y la estructura del menú en sí.No sé, por ejemplo, cómo evitar expandir el último término a ON_SWITCH(NULL).

¿O tal vez debería abordarlo desde otra forma?

¿Fue útil?

Solución

No puedes hacer una expansión de macro condicional en C, por lo que tu macro se expandirá de manera diferente dependiendo de los argumentos, como en:no puedes usar #if dentro de la definición de macro.

Supongo que lo mejor que podrías conseguir sería algo como MENU(blah, ITEM(blah,button), NULL, ITEM(blah,display), NULL), y aún necesita un conjunto separado para prototipos debido a la falta de expansión condicional.

Personalmente, escribiría un script simple para generar ese tipo de código C repetitivo.Uno que entienda la sintaxis deseada.En Python o lo que más te convenga…

Otros consejos

He escrito scripts de Python para generar este tipo de código para mí antes.Es posible que desee ir a esa ruta y simplemente trabajar el script en su proceso de compilación.

Puede programar condicionales, bucles finitos, argumentos predeterminados y todas estas cosas en el preprocesador solo.La biblioteca de BOOST tiene una implementación de parte de eso en su sección de preprocesador.El impulso es principalmente para C ++, pero las cosas del preprocesador también deben funcionar básicamente en C.

por tales técnicas Puede escribir macros complicadas, pero que son fáciles de usar.Se hace un poco más sencillo de implementar cuando se usa C99 en lugar de C89 (ha nombrado inicializadores y va_args ), pero aún.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top