Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在linux内核中从头开始实现容器__C_Linux_Struct_Linux Kernel_Linux Device Driver - Fatal编程技术网

C 如何在linux内核中从头开始实现容器_

C 如何在linux内核中从头开始实现容器_,c,linux,struct,linux-kernel,linux-device-driver,C,Linux,Struct,Linux Kernel,Linux Device Driver,我想从头开始实现宏/函数的容器_,就像linux内核中提供的那样,以从父结构的成员获取父结构的地址 e、 g.如果父结构是 结构父级{ int-id; 结构列表\头列表;} 我有结构中列表头元素的地址 所以我想得到struct parent的地址,这样我就可以访问父对象的id 我只有三个已知的信息 1.父结构的类型 2.结构列表头的类型 3.标识/列表头变量的名称 Thaks任何人都可以解释。首先,你的问题不合适。据我所知,您希望了解宏的工作原理,而不是实现它 继续 linux内核中使用的链表在

我想从头开始实现宏/函数的容器_,就像linux内核中提供的那样,以从父结构的成员获取父结构的地址

e、 g.如果父结构是

结构父级{ int-id; 结构列表\头列表;}

我有结构中列表头元素的地址

所以我想得到struct parent的地址,这样我就可以访问父对象的id

我只有三个已知的信息 1.父结构的类型 2.结构列表头的类型 3.标识/列表头变量的名称


Thaks任何人都可以解释。

首先,你的问题不合适。据我所知,您希望了解宏的工作原理,而不是实现它

继续

linux内核中使用的链表在

在linux内核中,列表包含在列表节点中。 例如:

因此,我们使用list_head变量迭代链表。棘手的部分是,我们使用list变量来获取节点结构(它包含在其中)

参见中的问题2.14和2.15。这个问题解释了如果我们在结构中有一个变量的偏移量,我们如何检索到包含结构的指针

所以用外行的话说,我们可以说

struct s address = <address of struct variable> - <offset of that variable in the struct>
因此,将左操作数视为结构变量(这通常是列表头变量)。现在转到正确的操作员。为了获得包含严格(比如struct my_list)中该变量(比如list_head变量)的偏移量,我们创建了一个零结构(即地址为0x0的临时结构),以便该结构中任何变量的地址都对应于该变量的偏移量

现在要理解的最后一部分是为什么强制转换为char*。这是一个基本的指针算法。char*addition会一次将值递增1(char*指向1字节的字符)

如果是int*的话,在指针上加1将使偏移量增加4,因为int*指向大小为4的int(在我的计算机上)


希望有帮助……)

首先,你的问题不合适。据我所知,您希望了解宏的工作原理,而不是实现它

继续

linux内核中使用的链表在

在linux内核中,列表包含在列表节点中。 例如:

因此,我们使用list_head变量迭代链表。棘手的部分是,我们使用list变量来获取节点结构(它包含在其中)

参见中的问题2.14和2.15。这个问题解释了如果我们在结构中有一个变量的偏移量,我们如何检索到包含结构的指针

所以用外行的话说,我们可以说

struct s address = <address of struct variable> - <offset of that variable in the struct>
因此,将左操作数视为结构变量(这通常是列表头变量)。现在转到正确的操作员。为了获得包含严格(比如struct my_list)中该变量(比如list_head变量)的偏移量,我们创建了一个零结构(即地址为0x0的临时结构),以便该结构中任何变量的地址都对应于该变量的偏移量

现在要理解的最后一部分是为什么强制转换为char*。这是一个基本的指针算法。char*addition会一次将值递增1(char*指向1字节的字符)

如果是int*的话,在指针上加1将使偏移量增加4,因为int*指向大小为4的int(在我的计算机上)


希望有帮助……)

为什么不从原来的宏观开始,根据你的需要进行调整?@chatraed:你指的是哪些“不必要的部分”?chatraed我想了解这个概念。然后,这可能是重复的:上面的帖子没有正确解释代码,只是给出了想法。为什么不从原始宏开始,根据需要进行调整?@chatraed:你指的是哪些“不必要的部分”?@chatraed我想了解这个概念。然后,这可能是重复的:上面的帖子没有正确解释代码,只是给出了想法。为什么不从原始宏开始,根据需要进行调整?@chatraed:你指的是哪些“不必要的部分”?@chatraed我想了解这个概念。然后,这可能是重复的:上面的文章没有正确解释代码,只是给出了想法。
struct s address = <address of struct variable> - <offset of that variable in the struct>
#define container_of(ptr, type, member) \
    (type *)((char *)(ptr) - (char *) &((type *)0)->member)
((char*)0) + 1  -> 0x1
((int*)0) + 1  -> 0x4