offsetof
offsetof() 和 container_of() 两个宏定义在linux内核中很常见。我们在应用程序编程时可能也需要用到,因此可以把这两个宏定义copy过来。
offsetof(type, member)用来求结构体type中的member成员在type中的偏移, 其定义如下:
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
例如对于结构体:
struct test_s {
int a;
int b;
int c;
};
那么 offsetof(struct test_s, c) 就等于8。
而container_of(ptr, type, member)宏用来通过结构体的某个成员的指针来获得指向整个结构体的指针。
/**
* 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) );})
其中,type是结构体的类型,member是结构体中这个成员的名字,ptr是指向这个成员的实例的指针。例如对于结构体:
struct cAMDev {
int a;
int c;
int b;
};
那么下面代码的结果就是将指针zzp指向了结构体zz。
struct camdev zz; //一个结构体实例
struct camdev * zzp;
zzp = container_of(&(zz.c), struct camdev, c);
当然这个代码只是举例用的,实际场景可能是,我们不知道zz在哪定义及其地址,但知道c是这个结构体的成员且知道c的指针,这时就可以用container_of获取zz的实例。
-
需要说明两点:
1. offsetof()宏展开后的内容是在编译阶段(编译过程的第二阶段)被处理掉的,而不是运行时,所以用0地址来取成员不会出现异常。
2. container_of()和offsetof()是内核中提供的宏,我们写应用程序时不能直接用,而是要重新定义。
随便再说一点:可计算的成员偏移都可以在编译阶段得出结果,例如我看到一个程序如下:
#include <stdio.h>
struct str{
int len;
char s[0];
};
struct foo {
struct str *a;
};
int main(int argc, char** argv) {
struct foo f={0};
if (f.a->s) {
printf("%x\n", f.a->s);
}
return 0;
}
这个程序执行时并不会报错,打印结果为4。因为虽然 f = {0} 是将a指向了NULL,但代码中printf是在打印 f.a->s 的地址,这在编译期间就可以算出来。如果把%x改为%s程序就崩溃了,因为你试图访问s指向的内容。
文章最后发布于: 2018-03-22 15:26:48
相关阅读
关于offsetof(s,m)的解析在一些库的写法中,我们有时会看到如下的宏定义:#define OFFSETOF(s,m) ((INT32U)&(((s *)0->m))其作用其实是
Linux下offsetof与container_of结构体
转载:http://www.cnblogs.com/skywang12345/p/3562146.html Linux中的两个经典宏定义 倘若你查看过Linux Kernel的源码,那么你对
在Linux内核源码中,实现和链表相关的接口list_entry()时,会调用container_of()宏定义,它的作用是:给定结构体中某个成员的地址、该结
offsetofRetrieves the offset of a member from the beginning of its parent structure.返回结构成员相对于结构开头的字节偏移
在linux 内核编程中,会经常见到一个宏函数container_of(ptr,type,member), 但是当你通过追踪源码时,像我们这样的一般人就会绝望了(