#define宏中#define的评估顺序

时间:2019-07-03 22:06:08

标签: c++ arduino menu macros

我正在为带有#define宏的Arduino项目创建菜单系统(受3D打印机上Marlin固件的启发),我试图对每个菜单项都使用宏#define MENU_ITEM_EDIT()进行概括。完整的代码真的很长,因此我省略了紧凑的代码块。但是,您可以在此处找到完整的代码:https://pastebin.com/h24itG9y

void draw_row(int row, char* value) { /* Stuff here*/ } // Draws row
char* uiToStr(int x) { /* Stuff here*/ } // Converts unsigned int to a string

#define disp_array(display, value)  display[value]
#define disp_func(display, value)   display(value)
#define disp_char(display, value)   display

#define MENU_ITEM_EDIT(min, max, rate, display, displayType, width, label, value) \
    // A bunch of stuff
    draw_row(rowNum, disp_ ## displayType(display, value)); \
    // More stuff

使用代码宏看起来像:

// Values
const char item1[] = "Item 1", item2[] = "Item 2", item3[] = "Item 3";
const char* const itemList[] = {item1, item2, item3};
int currentItem = 0;
uint8_t item1Val = 10;

void menu1() 
{
   START_MENU(); 
       MENU_ITEM_EDIT(0, 3, 1, itemList, array, 6, "Item:", currentItem);
       MENU_ITEM_EDIT(0, 255, 1, uiToStr, func, 3, "Item 1 Value:", item1Val);
   END_MENU();
}

显示为:

Item:     Item 1
Item 1 Value: 10     

为了方便我的菜单声明,我尝试使用常见的菜单类型,例如范围从0到255的uint8_t。然后,在菜单中,我将使用__u255_t而不是前6个参数。

#define __u255_t 0, 255, 1, uiToStr, func, 3

void menu2()
{
    int item2Val = 10;

    START_MENU(); 
        MENU_ITEM_EDIT(__u255_t, "Item 2 Value", item2Val);
    END_MENU();
}

以前,我已经进行了设置,以便每次我想要不同类型的菜单时,即使我只使用一次,也必须为其定义类型以及如何在宏中对其求值。这样,对于行中通常重复出现的类型,我可以使用1个参数而不是6个参数。但是,当行中包含一组唯一的参数(例如不同范围或显示字符串列表)的行时,我仍然希望能够使用6参数选项。

但是,在此示例中,该程序无法编译,因为它将__u255_t放入了min宏的MENU_ITEM_EDIT()中,而不是将__u255_t扩展为其6个值并将它们放入MENU_ITEM_EDIT()的前6个参数中。宏的计算结果为:

MENU_ITEM_EDIT(__u255_t, "Item 2 Value", item2Val);
// Evaluates as:
MENU_ITEM_EDIT( (0, 255, 1, uiToStr, func, 3), "Item 2 Value", item2val, , , , , );

注意:我加了一些括号以使其更清晰易懂。

但是我想要

MENU_ITEM_EDIT(__u255_t, "Item 2 Value", item2Val);
// Evaluates as:
MENU_ITEM_EDIT(0, 255, 1, uiToStr, func, 3, "Item 2 Value", item2Val);

我考虑过使用struct,但是我不确定是否可以使用,因为根据行的不同,value中的draw_row()字符串可以是函数或数组。有人对如何解决此问题有任何建议吗?

另外,如果需要添加更多代码以使问题更清楚,请告诉我。

0 个答案:

没有答案