Linux 中的列表条目

发布于 2024-10-30 18:46:30 字数 296 浏览 3 评论 0原文

user/include/linux/list.h

此声明:

#define list_entry(ptr, type, member) \
((type *)((char *)(ptr) – (unsigned long)(&((type *)0)->member)))

有人可以解释一下这是什么以及它是如何工作的,提前

致谢请尽可能简化你的答案,我了解Linux中的线程、进程,现在我正在探索可能性,但我对这个问题有点困惑。

user/include/linux/list.h

this declaration:

#define list_entry(ptr, type, member) \
((type *)((char *)(ptr) – (unsigned long)(&((type *)0)->member)))

can somebody please explain what is this and how does it work, thanks in advance

P.S. please simplify your answer as much as possible, I know about threads, processes in Linux, now I'm exploring possibilities and I'm a little bit stuck with this one.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

水水月牙 2024-11-06 18:46:30

考虑这样的两个结构:

struct data {
    int something;
};

struct container {
    int something_before;
    struct data data_item;
    int something_after;
};

假设您有一个指向 struct data 值的指针:

struct data *data_ptr;

list_entry() 宏可帮助您将 data_ptr 转换为指向保存 struct data 值的 struct 容器 值的指针,由 ptr 指向:

struct container *cont_ptr = list_entry(data_ptr, struct container, data_item);

该宏通过计算 的偏移量来工作data_itemstruct 容器 中,并从 data_ptr 指针中减去那么多字节。当转换为struct container *时,会给出一个指向“内部”保存此特定struct数据struct container的有效指针。

还可以使用内置的 offsetof() 宏来稍微简化该宏:

#define list_entry(ptr, type, member) \
    ((type *)((char *)(ptr) – offsetof(type, member)))

Consider two structs like this:

struct data {
    int something;
};

struct container {
    int something_before;
    struct data data_item;
    int something_after;
};

Assume you have a pointer to a struct data value:

struct data *data_ptr;

The list_entry() macro helps you to convert data_ptr to a pointer to the struct container value that holds the struct data value, pointed to by ptr:

struct container *cont_ptr = list_entry(data_ptr, struct container, data_item);

The macro works by computing the offset of data_item inside the struct container, and subtracting that many bytes from the data_ptr pointer. This, when cast to struct container *, gives a valid pointer to the struct container that holds this particular struct data "inside".

The macro can also be simplified a bit by using the builtin offsetof() macro:

#define list_entry(ptr, type, member) \
    ((type *)((char *)(ptr) – offsetof(type, member)))
掩耳倾听 2024-11-06 18:46:30

该宏用于查找给定其成员之一的结构的地址。

因此,例如,假设您有结构:

typedef struct
{
    int i;
    int j;
} typestruct;

您需要知道的第一件事是宏的最后部分:

 &((typestruct *)0)->j

用于给出成员的偏移量。因此,它是从内存转换为类型和成员的大小(以字节为单位)。在本例中,它是 sizeof(int),因为 j 就在 int i 下面;因此,为了简单起见,我们假设该表达式值为 4。使用宏可以得到相同的结果

offsetof(typestruct, j);

现在我们要计算temp的地址,其中temptypestruct temp。为此,我们简单地计算指针的地址减去成员位置。指针的地址是:

(typestruct *)((char *) &temp.j)

因此,减法是:

&temp ==  (typestruct *)((char *) &temp.j) - offsetof(typestruct, j)

或者,就像宏所说:

&temp ==  (typestruct *)((char *) &temp.j) - &((typestruct *)0)->j

你可以了解更多 此处,以及此问题

(括号是必要的,但为了澄清而被删除)

This macro is used to find the address of a struct given one of its member.

So, for example, suppose you have the struct:

typedef struct
{
    int i;
    int j;
} typestruct;

First thing you need to know is that the last part of the macro:

 &((typestruct *)0)->j

Is used to give the offset of a member. So, it is the size, in bytes, from the zero memory casted to the type, to the member. In this case, it is the sizeof(int), because j is just bellow int i; So lets assume this expression values 4 for simplicity. You can get the same result with the macro

offsetof(typestruct, j);

Now we want to calculate the address of temp, where temp is typestruct temp. To do that, we simple compute the address of the pointer minus the member position. The address of the pointer is:

(typestruct *)((char *) &temp.j)

Hence, the subtraction is:

&temp ==  (typestruct *)((char *) &temp.j) - offsetof(typestruct, j)

or, like the macro says:

&temp ==  (typestruct *)((char *) &temp.j) - &((typestruct *)0)->j

You can learn much more here, and also in this question.

(Parenthesis are necessary, but was eliminated for clarification)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文