The*_*ect 1 c linux macros kernel kernel-module
这样的标题听起来可能很愚蠢,但是我以前从未见过这样的东西,而且我真的不知道该如何描述它:
因此,我只是编写了第一个内核模块,并且使用了一个链表,该链表使用了linux/list.h头文件。其中有一个宏:
400 /**
401 * list_for_each_entry - iterate over list of given type
402 * @pos: the type * to use as a loop cursor.
403 * @head: the head for your list.
404 * @member: the name of the list_struct within the struct.
405 */
406 #define list_for_each_entry(pos, head, member) \
407 for (pos = list_entry((head)->next, typeof(*pos), member); \
408 prefetch(pos->member.next), &pos->member != (head); \
409 pos = list_entry(pos->member.next, typeof(*pos), member))
Run Code Online (Sandbox Code Playgroud)
而且,我用它是这样的(假设list_head是链表的头,并且list是list_struct在结构内):
struct thing *ptr;
list_for_each_entry(ptr, &list_head, list){
printk(KERN_INFO "contents: %s\n", ptr->something);
}
Run Code Online (Sandbox Code Playgroud)
当我运行时dmesg,列表中的每个项目都有一行...
所以,我的问题是:这里发生了什么?我以前从未见过像这样的宏那样使用过的宏-编写以这种方式调用的宏的规则是什么?
我只是真的不明白为什么这样做,或者我将如何编写自己的宏以这种方式工作。
宏只是在文本上扩展。没有魔法在发生。您可以使用查看输出gcc -E。在这种情况下:
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
prefetch(pos->member.next), &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
...
struct thing *ptr;
list_for_each_entry(ptr, &list_head, list){
printk(KERN_INFO "contents: %s\n", ptr->something);
}
Run Code Online (Sandbox Code Playgroud)
扩展为:
struct thing *ptr;
for (ptr = list_entry((&list_head)->next, typeof(*ptr), list);
prefetch(ptr->list.next), &ptr->list != (&list_head);
ptr = list_entry(ptr->list.next, typeof(*ptr), list)) {
printk(KERN_INFO "contents: %s\n", ptr->something);
}
Run Code Online (Sandbox Code Playgroud)
请注意,我在那里并没有做任何努力,只是剪切并粘贴了代码并进行了传递gcc -E(并略微整理了格式)。
循环(如您所见)是在扩展代码中完成的。
| 归档时间: |
|
| 查看次数: |
2247 次 |
| 最近记录: |