Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1119975
  • 博文数量: 91
  • 博客积分: 10053
  • 博客等级: 上将
  • 技术积分: 1335
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-01 12:46
文章分类
文章存档

2011年(4)

2010年(22)

2009年(22)

2008年(43)

分类: LINUX

2008-07-27 13:10:42

file_operation 结构中的open函数定义如下:
int (*open)(struct inode *inode, struct file* filp);

inode中含有i_cdev属性,它描述的是字符设备。在自己定义的字符设备中,一般会包含字符设备的指针,而open方法被调用时,通常需要获取特定的设备对象,这里就涉及到一个问题:如何通过结构中的某个变量获取结构本身的指针。Linux内核中提供了container_of宏(WDM中也定义了相似功能的宏)。C99中定义了两个宏,typeof和offsetof,它们返回的是某个变量的类型和结构中某变量在结构中的偏移量。可以预想的是,没有编译器的支持,container_of的宏是很难实现的(至少我还没有想出能够不用typeof宏实现container_of的方法)。

下面是container_of宏的标准实现:

container_of宏定义在[include/linux/kernel.h]中:

#define container_of(ptr, type, member)     \

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

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

offsetof宏定义在[include/linux/stddef.h]中:

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

值得一提的是,offsetof宏的实现非常巧妙,它把0地址转化为TYPE结构的指针,然后获取该结构中MEMBER成员的指针,并将其强制类型转换为size_t类型。于是,由于结构从0地址开始定义,因此,cast后的MEMBER成员地址,实际上就是它在结构中的偏移量。这也显示出了C语言中指针的强大。因为,在某个体系结构下实现的libc,结构中各个成员的偏移总是可以预见的,这比C#那种以托管的方式管理内存的自由度要大的多。


阅读(1293) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~