【问题标题】:Retrieve parent struct of a list_head object检索 list_head 对象的父结构
【发布时间】:2013-12-16 12:43:16
【问题描述】:

在 linux 内核中有一个 struct XX,其中包含一个 struct list_head YY

现在给定一个指向struct XX 对象的指针,我想在链表中找到所有XX 结构。所以我会遍历list_head结构,然后找到对应的父结构。

但是这里的第二步似乎不适用。所以我不确定是否有可能实现这一点。

例子:

struct XX {
    ...
    struct list_head YY;
};

【问题讨论】:

  • 您能举个例子说明您的问题吗?这个问题模棱两可。
  • @Mike 添加了 struct XX 定义

标签: c linux struct linked-list kernel


【解决方案1】:

您应该使用 container_of 宏 (LDD3 chapter 3: The open method)。

【讨论】:

  • 或者 Windows 上的 CONTAINING_RECORD 宏(你没有说你使用的是什么平台)。
【解决方案2】:

我想你是在问如何找到包含给定列表节点(你有一个指针)的对象。如果是这样,你想要这个宏的一些变体:

  //given the address of a member, find the address of the object containing the member.
  #define GetObjectFromMember(ObjectType,MemberName,MemberPointer) \
             ((ObjectType *)(((char *)MemberPointer) - ((char *)(&(((ObjectType *)0)->MemberName)))))

给定一个 struct Foo 和一个成员 m_bar,一个指向实例 m_bar 的指针 p:

Foo *foo = GetObjectFromMember(Foo,m_bar,p);
ASSERT( &foo->m_bar == p );

我在大量回调中使用此宏,在这些回调中,我得到了一个指向回调对象(如计时器)的指针,并且需要找到周围的对象指针。由于 linux 内核使用侵入式列表,我确信它已经在某个地方拥有这个宏,但我从来没有真正寻找过它。

【讨论】:

  • 从技术上讲,宏有点棘手 - 它取决于以特定方式表现的特定未定义行为。理想情况下,您应该使用平台供应商提供的宏,例如 Linux 上的 container_of 或 Windows DDK 上的 CONTAINING_RECORD。这些将保证与您正在使用的编译器一起使用。
  • 我已经使用这个精确的宏跨平台超过 15 年,所以我很确定它是稳定的。由于虚拟继承,该宏在 C++ 中确实存在问题。该宏的模板版本涵盖了这一点,但此问题未涵盖这一点。
  • 根据 C 和 C++ 语言,它仍然是未定义的行为。这并不意味着您不应该使用它,但这是您需要注意的事情。这是我的观点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多