libusb原始碼學習 list entry

2021-10-02 03:44:07 字數 2080 閱讀 1090

usb開發涉及到libusb,看了下原始碼,現在已經到了1.0.23版;全部用的c,編譯器和平台的普適性相對比較強;

其中的list_head作為關鍵鍊錶,也是各個鏈結結構的成員(member)變數。而利用這個成員變數完成各個結構鏈結,涉及到幾個很有意思的巨集,其中包括list_entry,list_for_each_entry,這種用法和我們最普通的用法有點區別:在c ++中,通常我用標準std::list, std::vector實現;在c中,我們往往直接使用結構自自身的指標來完成鏈結,而不是使用這種成員鏈結指標(list_head)。

寫了個list_entry應用原理的解析,用3種完全等價的方式找到:dev->session_data == 2

#include struct list_head ;

/* get an entry from the list

* ptr - the address of this list_head element in "type"

* type - the data type that contains "member"

* member - the list_head element in "type"

*/#define list_entry(ptr, type, member) \

((type *)((uintptr_t)(ptr) - (uintptr_t)offsetof(type, member)))

#define list_first_entry(ptr, type, member) \

list_entry((ptr)->next, type, member)

/* get each entry from a list

* pos - a structure pointer has a "member" element

* head - list head

* member - the list_head element in "pos"

* type - the type of the first parameter

*/#define list_for_each_entry(pos, head, member, type) \

for (pos = list_entry((head)->next, type, member); \

&pos->member != (head); \

pos = list_entry(pos->member.next, type, member))

#define list_for_each_entry_safe(pos, n, head, member, type) \

for (pos = list_entry((head)->next, type, member), \

n = list_entry(pos->member.next, type, member); \

&pos->member != (head); \

pos = n, n = list_entry(n->member.next, type, member))

#define list_empty(entry) ((entry)->next == (entry))

struct libusb_device ;

libusb_device* list_entry_func(list_head* ptr)

int main()

for (dev = list_entry_func(usb_devs.next);

&dev->list != &usb_devs;

dev = list_entry_func(dev->list.next))

}; for (dev = list_entry(usb_devs.next, libusb_device, list);

&dev->list != &usb_devs;

dev = list_entry(dev->list.next, libusb_device, list))

if (dev->session_data == 2)

return 0;

}

Java原始碼學習之List

是一種有序的容器 也被稱為序列 使用者可以精確地控制每一元素在list中的插入位置。使用者可以通過元素的索引獲得該元素並且搜尋list中的元素。不同於set,list允許重複的元素。list介面在collection介面之外對iterator,add,remove,equals,hashcode方法...

List原始碼分析

list 是繼承colection的介面 我們主要學習他的實現類 arraylist 和 linkedlist arraylist是基於陣列實現的 與陣列不同的是 它可以存放不同的資料型別的資料而且長度不定 我們分析一下他的底程實現 新增過程 public boolean add e e 如何做到長...

STL原始碼剖析學習五 list

每次插入或者刪除乙個元素,就配置或者釋放空間。插入和刪除元素操作都是常數時間。list的節點 template struct list node 是乙個雙向鍊錶 list的迭代器 不能用普通指標作為迭代器 typedef list node link type link type node list...