栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Linux中的offsetof/container

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux中的offsetof/container

offsetof宏

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

offsetof宏作用
用于计算结构体成员在结构体中的偏移量

offsetof宏原理
TYPE : 结构体的类型

MEMBER : 结构体成员

使用结构体类型定义一个指针并指向结构体成员,表示该地址从0开始到结构体成员地址的偏移,即可计算出偏移量。

container_of宏

#define  container_of(ptr, type, member)   ({
                                           const typeof( ((type *)0) -> member ) *_mptr = (ptr);
                                           (type *)( (char *)_mptr - offsetof(type, member) );})

container_of宏作用
根据结构体某成员变量计算结构体的首地址

container_of宏原理
ptr : 结构体成员地址

type : 结构体类型

member : 结构体成员变量

const typeof( ((type *)0) -> member ) *_mptr = (ptr);该语句表示使用结构体类型的指针指向成员member,进而获取结构体成员member的类型,使用该类型定义一个指针 _mptr保存结构体的成员地址ptr。

(type *)( (char *)_mptr - offsetof(type, member) );该语句表示把 _mptr强制转换为char *类型减去member在结构体中的偏移量即可获取首地址,再把获取到的首地址强制转换为结构体类型的指针返回。

该宏为语句表达式,语句表达式的返回值为最后一条语句的结果,因此container_of宏返回的是结构体类型的指针,指向结构体的首地址。

示例

#include 


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


#define  container_of(ptr, type, member)   ({
                                           const typeof( ((type *)0) -> member ) *_mptr = (ptr);
                                           (type *)( (char *)_mptr - offsetof(type, member) );})

struct student
{
   int age;
   int num;
   int math;
};

int main(void)
{
   
   struct student stu = {10, 20, 30};

   
   int *ptr = &stu.num;

   
   struct student *header_add = NULL;

   
   header_add = container_of(ptr, struct student, num);

   
   printf("num offsetof in stu = %drn", offsetof(struct student, num));

   
   printf("container_of header_add = %#prn", header_add);

   
   printf("stu header_add = %#prn", &stu);

   
   printf("header_add -> math = %drn", header_add -> math);

   return 0;
}

上述代码运行后输出如下:

num offsetof in stu = 4

container_of header_add = 0x0061FEB8

stu header_add = 0x0061FEB8

header_add -> math = 30
可以发现使用container_of计算出来的结构体首地址和直接打印出来的结构体首地址相同,表示该宏可以获取结构体的首地址。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/311620.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号