- 论坛徽章:
- 9
|
对于上面这个问题,我写了测试代码之后发现,
当我们要通过一个 struct hlist_node 获得它的前一个 struct hlist_node 的实现存在差别,测试代码如下:
1. 如果 struct hlist_node {
struct hlist_node *next,**prev;
};
void TestCase(void)
{
struct hlist_node *node; //已知
struct hlist_node *prev_node;
prev_node = (struct hlist_node *)(unsigned long)(node->pprev);
}
通过这种方法就可以获得 struct hlist_node 的前一个 struct hlist_node.
2. 如果 struct hlist_node {
struct hlist_node **pprev,*next;
};
void TestCase(void)
{
struct hlist_node *node; // 已知
struct hlist_node *prev_node;
prev_node = container_of(node->pprev,struct hlist_node,next);
}
通过这种方法可以获得 struct hlist_node 的前一个 struct hlist_node.
归其上面因为 struct hlist_node 成员分布不同导致这个问题的原因是:
void hlist_add_head(struct hlist_node *node,struct hlist_head *head)
{
struct hlist_node *first = head->first;
node->next = first;
if(first)
first->pprev = &node->next; // 因为这里 &node->next 的地址与 struct hlist_node 地址之间关系差别导致上面的差异.
head->first = node;
node->pprev = &head->first;
}
如上面源码所示:
struct hlist_node {
struct hlist_node *next,**pprev;
};
这样的定义结构是 next 的地址和 struct hlist_node 的地址是一样的.
而
struct hlist_node {
struct hlist_node **pprev,*next;
};
这样定义结构是 next 的地址和 struct hlist_node 之间是有差异的,需要使用 container_of 去转换他们的地址. |
|