wl_list 链表
wayland-util.h
struct wl_list { /** Previous list element */ struct wl_list *prev; /** Next list element */ struct wl_list *next; };
如果知道一个结构体成员的地址,就可以反推到这个结构体的地址
#define wl_container_of(ptr, sample, member) \ (__typeof__(sample))((char *)(ptr) - \ offsetof(__typeof__(*sample), member))
offsetof 这个是C语言标准里面提供的获取成员偏移量的宏,整个宏就是提供成员变量的地址获取到整个结构体的地址
举个例子:
struct example_container { struct wl_list list; int a; }; \param ptr 一个有效的指向wl_list的指针 \param sample 一个结构体指针(随便一个,甚至可以null),该结构体包含wl_list \param member 结构体的member 实例: struct example_container *container; container = wl_container_of(ptr, container, list) 通过这种方式,我们就可以得到container的实际地址 计算过程是这样的: 1. 因为ptr是个有效的地址,且ptr在struct example_container中 2. 我们拿到ptr的地址,减去其对应的member在结构体中的偏移,就可以得到example_container的首地址
有了上述方法,wayland扩展了很多宏, 比如 wl_list_for_each(pos, head, member)
struct message { char * contents; wl_list link; }; struct wl_list* message_list; //message_list中有很多messages struct message *m; wl_list_for_each(m, message_list, link) { do_something_with_message(m); } //翻译一下上述宏的工作原理如下: for(m = wl_container_of(message_list->next, m, link); &m->link != message_list; m = wl_contanier_of(m->link.next, m, link ) ) { do_something_with_message(m); }