当前位置: 首页 > article >正文

【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 宏集中管理全局变量,减少代码更简洁,同时提升代码可维护性;


http://www.kler.cn/a/573044.html

相关文章:

  • MySQL 数据库连接池爆满问题排查与解决
  • STM32---FreeRTOS临界段与任务调度器
  • 华为od机试-缓存需要最少金币数 /静态扫描(java)
  • 【C++设计模式】第四篇:建造者模式(Builder)
  • 机器学习-决策树详细解释
  • 算法进阶——枚举
  • 构建智能 SQL 查询代理agent,把整个查询过程模块化,既能自动判断使用哪些表,又能自动生成 SQL 语句,最终返回查询结果
  • 敏捷开发之自动化流水线
  • Ubuntu ollama 指定 gpu devices
  • 【VS2019】 .Net Core 3.1 无法打开项目文件
  • MagicArticulate: Make Your 3D Models Articulation-Ready 论文解读
  • SSE 和 WebSocket 的对比
  • 如何在Spring Boot中读取JAR包内resources目录下文件
  • 【封闭式】论文写作技巧--集中学习+集中写作
  • 高并发应用分层架构
  • 【MySQL】索引|作用|底层数据结构|常见问题
  • unity6 打包webgl注意事项
  • sqli-lab靶场学习(七)——Less23-25(关键字被过滤、二次注入)
  • 【Linux】http 协议
  • 如何通过卷积神经网络(CNN)有效地提取图像的局部特征,并在CIFAR-10数据集上实现高精度的分类?