wayland 学习笔记(一)

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);  
  }





原文地址:https://www.cnblogs.com/Arnold-Zhang/p/15266975.html