uclinux内核的container_of

本文解析了内核中常用的container_of宏的工作原理,该宏用于从结构体成员指针转换到包含该成员的完整结构体指针。通过示例介绍了如何在平台设备匹配函数中应用此宏。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

快乐虾

http://blog.youkuaiyun.com/lights_joy/

lights@hb165.com

本文适用于

ADSP-BF561

uclinux-2008r1.5-rc3 (smp patch)

欢迎转载,但请保留作者信息

内核中大量使用container_of这个宏,用以进行数据结构的向上转换,比如这样一段代码:

static int platform_match(struct device * dev, struct device_driver * drv)

{

struct platform_device *pdev = container_of(dev, struct platform_device, dev);

return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0);

}

在这里struct platform_device定义为:

struct platform_device {

const char * name;

u32 id;

struct device dev;

u32 num_resources;

struct resource * resource;

};

注意,在这个结构体里面包含了一个叫device的结构体,可以将struct platform_device称为父结构体,将struct device称为子结构体。

在上述函数中,传递进来的dev指针将指向platform_device这个父结构体中的dev成员,而contianer_of这个宏的作用则在于通过这个结构体成员的指针获得其父结构体的指针,在这里就是platform_device这一结构体的指针。

要达到这一目的很容易,只要将这个成员的指针减去此成员在整个结构体内的偏移量自然就可以了。看看container_of的定义:

/**

* container_of - cast a member of a structure out to the containing structure

* @ptr: the pointer to the member.

* @type: the type of the container struct this is embedded in.

* @member: the name of the member within the struct.

*

*/

#define container_of(ptr, type, member) ({ \

const typeof( ((type *)0)->member ) *__mptr = (ptr); \

(type *)( (char *)__mptr - offsetof(type,member) );})

这个宏定义的第一行构建一个叫__mptr的临时变量,实际上并不是必须的,它的作用只是强制编译器对数据类型进行检查。第二行里面的__mptr实际就是子结构体成员的指针。

偏移量的计算由offsetof宏完成:

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

这种方法到处都在用,没什么新奇的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值