0

我有一些结构要初始化,手动执行会很乏味。我想创建一个可以帮助我的宏......但我不确定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)的事情,但是有什么办法:

  • 使其更短(NULL 或某个名称)
  • ON_BUTTON(...);从结构之前删除需要

理想情况下,我想MENU(blah, button, NULL, display, NULL)同时定义处理程序和菜单结构本身。例如,我不知道如何防止将最后一个术语扩展为ON_SWITCH(NULL).

或者也许我应该以其他方式接近它?

4

3 回答 3

1

我以前写过 Python 脚本来为我生成这种代码。您可能想走那条路,只需将脚本用于您的构建过程。

于 2010-07-15T20:34:28.523 回答
0

您不能在 C 中进行条件宏扩展,因此您的宏将根据参数进行不同的扩展,例如:您不能在宏定义中使用 #if。

我想你能得到的最好的东西是MENU(blah, ITEM(blah,button), NULL, ITEM(blah,display), NULL),由于缺乏条件扩展,你仍然需要一个单独的原型集。

就个人而言,我会编写一个简单的脚本来生成那种样板 C 代码。一种可以理解您所需语法的方法。在 Python 或任何最适合您的...</p>

于 2010-07-15T20:26:48.887 回答
0

您可以单独在预处理器中编写条件、有限循环、默认参数和所有此类内容。Boost 库在其预处理器部分中实现了其中的一些。Boost 主要用于 C++,但预处理器的东西基本上也应该在 C 中工作。

通过这些技术,您可以编写复杂但易于使用的宏。使用 C99 而不是 C89(您已命名初始化程序和VA_ARGS)时,实现起来会更简单一些,但仍然如此。

于 2010-07-15T22:08:02.767 回答