Pergunta

Eu tenho algumas estruturas para inicializar, o que seria tedioso para o fazer manualmente.Eu gostaria de criar uma macro que irá me ajudar com isso...mas não tenho certeza se o C pré-processador é bom o suficiente para isso.

Eu tenho estruturas que representam os menus.Eles consistem de ponteiros de função apenas:

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;

Que me permite escrever as funções e funções separadas como (.c arquivo):

ON_BUTTON(blah) { ... }

e os menus (.h ficheiro):

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

Existe alguma maneira eu posso dobrar a definição de menu para definir?Eu poderia fazer algo que se expande MENU(blah, menu_frame_blah_button, NULL, menu_frame_blah_display, NULL) claro, mas existe alguma maneira para:

  • fazê-lo mais curto (NULO ou nome)
  • remover a necessidade de ON_BUTTON(...); desde antes da struct

Idealmente, eu gostaria de MENU(blah, button, NULL, display, NULL) tanto para definir as rotinas de tratamento e o menu de estrutura própria.Eu não sei, por exemplo, como para impedir a expandir o último prazo para ON_SWITCH(NULL).

Ou talvez eu deveria abordá-lo de alguma outra forma?

Foi útil?

Solução

Você não pode fazer condicional expansão de macro em C, de modo que seu macro deve ser expandida de forma diferente dependendo dos argumentos, como em:você não pode usar #se dentro de definição de macro.

Eu acho que o melhor que você poderia obter seria algo como MENU(blah, ITEM(blah,button), NULL, ITEM(blah,display), NULL), e você ainda precisa de um conjunto separado de protótipos devido a falta de condicional de expansão.

Pessoalmente, eu iria escrever um script simples para gerar esse tipo de clichê C código.Que o levaria a compreender o desejado de sintaxe.Em Python ou que for melhor para você...

Outras dicas

Eu tenho escrito scripts em Python para gerar este tipo de código para mim antes.Você pode querer ir por esse caminho e apenas trabalhar o script em seu processo de criação.

Você pode programar condicionais, finito loops, argumentos padrão e todas essas coisas no pré-processador sozinho.O Impulso biblioteca tem uma implementação de alguns dos que, em sua seção de pré-processamento.Boost é, principalmente, para o C++, mas o pré-processamento do material deve basicamente funciona em C bem.

Por essas técnicas você pode escrever macros complicados, mas que são simples de usar.Ele fica um pouco mais fácil de implementar quando usando C99 em vez de C89 (você ter chamado os inicializadores e VA_ARGS), mas ainda assim.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top