【C语言】宏定义中X-Micro的使用

C语言宏定义中X-Micro的使用

在LVGL源码中,全局变量初始化,以及函数声明和定义(LV_ROOTS)的时候的时候,使用到了X-Micro,下面拆解一下这个宏的用法。

下列代码来自:lv_gc.h 头文件

#define LV_DISPATCH(f, t, n)            f(t, n)

#define LV_ITERATE_ROOTS(f)                                                                            \
    LV_DISPATCH(f, lv_ll_t, _lv_timer_ll) /*Linked list to store the lv_timers*/                       \
    LV_DISPATCH(f, lv_ll_t, _lv_disp_ll)  /*Linked list of display device*/                            \
    LV_DISPATCH(f, lv_ll_t, _lv_indev_ll) /*Linked list of input device*/                              \
    LV_DISPATCH(f, lv_ll_t, _lv_fsdrv_ll)                                                              \
    LV_DISPATCH(f, lv_ll_t, _lv_anim_ll)                                                               \
    LV_DISPATCH(f, lv_ll_t, _lv_group_ll)                                                              \
    LV_DISPATCH(f, lv_ll_t, _lv_img_decoder_ll)                                                        \
    LV_DISPATCH(f, lv_ll_t, _lv_obj_style_trans_ll)                                                    \
    LV_DISPATCH(f, lv_layout_dsc_t *, _lv_layout_list)                                                 \
    LV_DISPATCH_COND(f, _lv_img_cache_entry_t*, _lv_img_cache_array, LV_IMG_CACHE_DEF, 1)              \
    LV_DISPATCH_COND(f, _lv_img_cache_entry_t, _lv_img_cache_single, LV_IMG_CACHE_DEF, 0)              \
    LV_DISPATCH(f, lv_timer_t*, _lv_timer_act)                                                         \
    LV_DISPATCH(f, lv_mem_buf_arr_t , lv_mem_buf)                                                      \
    LV_DISPATCH_COND(f, _lv_draw_mask_radius_circle_dsc_arr_t , _lv_circle_cache, LV_DRAW_COMPLEX, 1)  \
    LV_DISPATCH_COND(f, _lv_draw_mask_saved_arr_t , _lv_draw_mask_list, LV_DRAW_COMPLEX, 1)            \
    LV_DISPATCH(f, void * , _lv_theme_default_styles)                                                  \
    LV_DISPATCH(f, void * , _lv_theme_basic_styles)                                                  \
    LV_DISPATCH_COND(f, uint8_t *, _lv_font_decompr_buf, LV_USE_FONT_COMPRESSED, 1)                    \
    LV_DISPATCH(f, uint8_t * , _lv_grad_cache_mem)

#define LV_DEFINE_ROOT(root_type, root_name) root_type root_name;
#define LV_ROOTS LV_ITERATE_ROOTS(LV_DEFINE_ROOT)

#define LV_GC_ROOT(x) x
#define LV_EXTERN_ROOT(root_type, root_name) extern root_type root_name;
LV_ITERATE_ROOTS(LV_EXTERN_ROOT)

在LVGL中,调用 LV_ROOTS 宏声明全局变量,下面拆解宏,宏的拆解从内到外,由于前面

#define LV_DISPATCH(f, t, n)            f(t, n)
#define LV_ITERATE_ROOTS(f)                                                               \
    f(lv_ll_t, _lv_timer_ll) /*Linked list to store the lv_timers*/                       \
    f(lv_ll_t, _lv_disp_ll)  /*Linked list of display device*/                            \
    f(lv_ll_t, _lv_indev_ll) /*Linked list of input device*/ 
    ...... // 其余省略

根据这条宏定义:

LV_DEFINE_ROOT(root_type, root_name) root_type root_name;

把 f 替换为 LV_DEFINE_ROOT,因此就变为:

#define LV_ITERATE_ROOTS(LV_DEFINE_ROOT)                                                               \
    LV_DEFINE_ROOT(lv_ll_t, _lv_timer_ll) /*Linked list to store the lv_timers*/                       \
    LV_DEFINE_ROOT(lv_ll_t, _lv_disp_ll)  /*Linked list of display device*/                            \
    LV_DEFINE_ROOT(lv_ll_t, _lv_indev_ll) /*Linked list of input device*/ 
    ...... // 其余省略

LV_DEFINE_ROOT(lv_ll_t, _lv_timer_ll)

展开之后便是:

lv_ll_t  _lv_timer_ll;

其他的同理,因此这里就对全局链表进行了声明;

如果要把全局变量属性设置为extern,给外部文件使用,只需要修改一下宏,改为下面这种形式,只需要修改一下 宏定义,就可以完成所有全局变量的声明:

#define LV_EXTERN_ROOT(root_type, root_name) extern root_type root_name;
LV_ITERATE_ROOTS(LV_EXTERN_ROOT)

总结:

使用 X-Macro 宏集中管理全局变量,减少代码更简洁,同时提升代码可维护性;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值