linux container_of宏

2024-05-09 03:36
文章标签 linux container

本文主要是介绍linux container_of宏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1 结构体

假如我们有一个结构体Student,其定义如下:

typedef struct student
{int id;char name[30];int math;
}Student;

通过Student stu定义stu变量后,我们可以通过stu.id或stu.name来获取stu的成员。但如果想反过来,通过stu.id或者stu.name来获取stu变量的起始地址好像就没那么简单了,linux中的container_of宏就是为解决此问题而生的。 

2 container_of

在linux中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) ({				\void *__mptr = (void *)(ptr);					\BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) &&	\!__same_type(*(ptr), void),			\"pointer type mismatch in container_of()");	\((type *)(__mptr - offsetof(type, member))); })

container_of宏的包含3个参数:ptr、type和member,分别说明如下:

ptr: 第三个参数member的地址,这里可以理解为&stu.id或&stu.name;

type: 包含ptr的结构体名称,这里可以理解为Student;

member: ptr在结构体中的成员名。

为便于理解,我们通过用程序代码模拟如下:

#include <stdio.h>
#include <string.h>#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) );})typedef struct student
{int id;char name[30];int math;
}Student;int main()
{Student stu;Student *sptr = NULL;int *idPtr;char *namePtr;int *mathPtr;idPtr   = &stu.id;namePtr = (char*)&stu.name;mathPtr = &stu.math;printf("idPtr   = %p\n", idPtr);printf("namePtr = %p\n", namePtr);printf("mathPtr = %p\n", mathPtr);stu.id = 110;strcpy(stu.name,"guodegang");stu.math = 100;sptr = container_of(idPtr, Student,id);printf("container ptr = %p\n",sptr);sptr = container_of(namePtr, Student,name);printf("container ptr = %p\n",sptr);sptr = container_of(mathPtr, Student,math);printf("container ptr = %p\n",sptr);return 0;
}

运行结果:

idPtr   = 0x7ffc75765a70
namePtr = 0x7ffc75765a74
mathPtr = 0x7ffc75765a94
container ptr = 0x7ffc75765a70
container ptr = 0x7ffc75765a70
container ptr = 0x7ffc75765a70
idPtr实际就是stu变量的地址,namePtr对应的是stu.name地址,mathPtr对应的是stu.math地址。

后面通过idPtr、namePtr、mathPtr都可以成功取得stu变量的地址。

这篇关于linux container_of宏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/972278

相关文章

Linux脚本重定向

Shell中可能经常能看到:>/dev/null  2>&1  eg:sudo kill -9 `ps -elf |grep -v grep|grep $1|awk '{print $4}'` 1>/dev/null 2>/dev/null 命令的结果可以通过%>的形式来定义输出 /dev/null 代表空设备文件 > 代表重定向到哪里,例如:echo "123" > /home/1

Linux下网卡开机自动加载

新安装的虚拟机发现自动起不了网卡接口,每次启动都要 # ifup ens33 则比较麻烦,将下面eht1改成自己的网卡名称的文件修改即可 编辑/etc/sysconfig/network-scripts/ifcfg-eth1 ONBOOT=yes

Linux删除大文件rm -rf的问题

请几天,我删除系统汇总的大文件,大约100G左右,当我使用rm -rf  xxxx.log删除后,使用df -h发现空间并未释放。 一开始以为是由于磁盘虚拟挂载,导致我删除的文件并不是当前目录的文件。但后来发现并不是。 我在网络上搜索发现都是  要: lsof | grep delete kill -9 xxx 但是我觉得这样不安全。 比如文件被进程锁定,或者有进程一直在向这个文件写数

pl- 配置远程打印机,用linux命令行打印

问题来源: 实验室打印机认证过我台式机的IP,但是里面只有linux命令行界面,只当作服务器用…又不想每次用笔记本想打印都折腾换网线…so… 问题描述:如何用命令行连接网络打印机,并用命令行控制打印 工具:pladmin 配置, pl 打印 参考资料: 在 Oracle® Solaris 11.2 中配置和管理打印 极客学院happypeter1983 打印(可以看参数) 材料: 打印

linux ndk编译搭建测试

一、ndk下载 NDK 下载  |  Android NDK  |  Android Developers 二、ndk环境变量配置 ndk解压: unzip android-ndk-r26d-linux.zip  环境变量配置:  export NDK_HOME=/rd/own/test/android-ndk-r26d/  export PATH=$PATH:$NDK_HOME

dom4j处理xml在linux环境下中文乱码

最近在搞一个webservice 的soap接口数据同步,接口提供方就是个鸟人,两个接口来来回回写了2个月才调通,我也真是服了 ———**——– 好了吐槽到此结束,下面说说乱码的问题 dom4j 解析xml 就是一个把字符串、文件、输入流转换成文本(Document )再处理的过程;下面附上代码 InputStream in = new ByteArrayInputStream(fyxx.

【LinuxC++】Linux环境下C++编程

在阅读的过程中有任何问题,欢迎一起交流 邮箱:1494713801@qq.com   QQ:1494713801   在linux下,开发工具被切割成一个个独立的小工具。各自处理不同的问题。例如: 编辑器(emacs, vim)用来进行编辑程序的 调试器(gdb) 用来调试程序 编译器(GCC) 用来编译和链接程序的 性能分析工具(gcov, gprof) 用来优化程序的 文档生成器

Linux系统下qtcreator每次打开文件都要重新编码问题

在Linux系统下qtcreator每次打开windows系统下的.c文件都会提示编码问题, 提示错误:“Could not decode “xxx” with “UTF-8”-encoding. Editing not possible "中文显示乱码,不能编译,如下图: 解决: 1、点击上面错误提示条右边“Select Encodeeing”按钮 选GBK / windows-936…,按编

编译报错go: unsupported GOOS/GOARCH pair linux /amd64

目录 背景 解决 背景 在windows下交叉编译go程序,目标平台是linux、amd64。 执行指令: GOOS=linux GOARCH=amd64 go build -v或set GOOS=linux & set GOARCH=amd64 & go build -v 报错 go: unsupported GOOS/GOARCH pair linux /amd64

Linux搭建Tomcat+MySQL环境

以阿里云上最新安装好的Centos8为例,SSH工具是FinalShell 更新yum到阿里云的源 我这边安装好之后yum源已经是国内的了,所以实际上这一步可以省略,如果出现安装软件时下载速度很慢,可以通过这一步修改yum源 cd /etc/yum.repos.d 如下图所示 对着CentOS-Base.repo文件右键点打开,之后将https://mirrors.aliyun.com/re