GCC-C语言“自定义段”
一、起因
事情的起因是这样的,在看别人代码时,发现了一种很有意思的写法,因为本人主要是以应用层开发为主,所以对这种写法还是比较少见的,所以研究了一下,就牵扯出了一些知识点,这里先卖个关子,继续往下看。
二、经过
发现了一串这样的代码
static void do_mac(mcmd_t *mcmd, char *params)
{}
MIIO_CMD(mac, do_mac, NULL);
这个是明显是串口数据的处理回调。进入MIIO_CMD看一下
#define MIIO_CMD_ADDON_NAME cmd
#define MIIO_CMD(_name, _cmd, _tip) \miio_addon_entry_complete(MIIO_CMD_ADDON_NAME, _name, _cmd, _tip, 0)
这里面就是一个宏定义,再进入 miio_addon_entry_complete 看一下
#define miio_addon_entry_complete(_addon, _name, _value, _tip, _acm) \miio_addon_entry_declare(_addon, _name) = miio_addon_value_complete(_addon, _name, _value, _tip, _acm)
这里面调用了 miio_addon_value_complete 赋值给了 miio_addon_entry_declare
先看 miio_addon_value_complete
#define __miio_addon_acm_assignment(_acm) , .acm = (_acm) & 0B11#define _miio_addon_value_complete(_addon, _name, _value, _tip, _acm){.name = #_name, .full_name = #_addon"."#_name, .value = _value, .tip = _tip __miio_addon_acm_assignment(_acm)}
#define miio_addon_value_complete(_addon, _name, _value, _tip, _acm) _miio_addon_value_complete(_addon, _name, _value, _tip, _acm)
这里面就是赋值,把入口参数赋值给结构体的各个元素。
这里介绍一个#参数,防止有些朋友不太懂。
#是一个字符串化操作符。就是把参数转化为字符串。例如下面这段代码
#define TO_STR(s) #sint a = 123;
printf("%s",TO_STR(a));
代码的含义就是把Int类型的变量a转化为字符串类型,并且输出。
好,言归正传。再看 miio_addon_entry_declare 参数
#define _miio_addon_entry_declare(_addon, _name) \miio_addon_symbol_t _miio_addon_list_2_##_addon##_2_##_name \__attribute__((aligned(4))) \__attribute__((unused, section(".miio_addon_list_2_"#_addon"_2_"#_name)))
#define miio_addon_entry_declare(_addon, _name) _miio_addon_entry_declare(_addon, _name)
这里面有个 miio_addon_symbol_t 结构体,看一下
typedef struct miio_addon_symbol_s {const char* name;const char* full_name;void* value;const char* tip;const uint8_t acm;
}miio_addon_symbol_t;
这里面的元素就是 miio_addon_value_complete 宏定义的赋值。
#define _miio_ad