Linux内核中的常用宏container_of其实很简单

开发平台:Ubuntu11.04

编 译器:gcc version 4.5.2 (Ubuntu/Linaro4.5.2-8ubuntu4)

Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址。

Container_of的定义如下:

其实它的语法很简单,只是一些指针的灵活应用,它分两步:

第一步,,首先定义一个临时的数据类型(通过typeof( ((type *)0)->member )获得)与ptr相同的指针变量__mptr,然后用它来保存ptr的值。

第二步,用(char *)__mptr减去member在结构体中的偏移量,得到的值就是整个结构体变量的首地址(整个宏的返回值就是这个首地址)。

其中的语法难点就是如何得出成员相对结构体的偏移量?

通过例子说明,如清单1:

说明,__builtin_offsetof(a,b)是GCC的内置函数,可认为它的实现与((size_t) &((TYPE *)0)->MEMBER)这段代码是一致的。

例子输出结果:

其中代码难以理解的地方就是它灵活地运用了0地址。如果觉得&( (structtest_struct *)0 )->ch这样的代码不好理解,那么我们可以假设在0地址分配了一个结构体变量structtest_struct a,然后定义结构体指针变量p并指向a(struct test_struct *p = &a),如此我们就可以通过&p->ch获得成员ch的地址。由于a的首地址为0x0,所以成员ch的首地址为0x4。

最后通过强制类型转换(size_t)把一个地址值转换为一个整数。

分析完container_of的定义,接下来举两个例子来体会一下它的使用方法。

正确的例子,如清单2:

例子输出结果:

不适当的例子,如清单3:

例子输出结果:

注意,由于这里并没有一个具体的结构体变量,所以成员num和fl的值是不确定的。

寂寞的人总是记住生命中出现的每一个人,

Linux内核中的常用宏container_of其实很简单

相关文章:

你感兴趣的文章:

标签云: