Linux结构体变量报错,23. Linux模式设计
23.6. 结构体成员互访
由于内核中定义了很多复杂的数据结构,而它们的实例中的成员在作为函数参数传递的时,函数中可能需要对它的包含者中的其他的兄弟成员进行处理,这就需要只根据成员地址就可以获取整个结构体变量的地址的操作。container_of提供了这样的操作:include/linux/kernel.h
/**
* 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) );})
巧妇难为无米之炊,无论如何,都需要告知container_of该整体结构体变量的类型以及当前成员的指针和成员名。typeof用来获取成员的类型并定义一个临时变量__mptr来存储当前成员的地址。offsetof用来获取当前成员相对于整体结构体地址的偏移。它定义为:include/linux/compiler-gcc4.h
#define __compiler_offsetof(a,b) __builtin_offsetof(a,b)
include/linux/stddef.h
#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
如果定义了__compiler_offsetof,则使用Gcc编译器内建的offsetof宏,它的作用和此处定义的offsetof相同。它将0地址作为当前结构的首地址,从而直接通过指针访问成员得到的地址即为偏移。将实际使用的结构体中的成员指针__mptr减去offsetof,就得到了结构体的地址。#include
......
typedef struct man
{
char name[32];
unsigned int id;
unsigned char age;
char address[64];
}man_t;
int main()
{
man_t tom = {"Tom", 0, 24, "ShangHai China"};
man_t *man = NULL;
printf("tom:%p, tom.age:%p, offsetof(man_t, age): %d\n",
&tom, &tom.age, offsetof(man_t, age));
man = container_of(&tom.age, man_t, age);
printf("tom.name:%s, tom.id:%d, tom.age:%u, tom.address:%s\n",
man->name, man->id, man->age, man->address);
return 0;
}
测试结果如下:tom:0xbf85cda4, tom.age:0xbf85cdc8, offsetof(man_t, age): 36
tom.name:Tom, tom.id:0, tom.age:24, tom.address:ShangHai China
Linux结构体变量报错,23. Linux模式设计相关推荐
- Linux结构体变量报错,C语言中的结构体
用户自己建立自己的结构体类型 1. 定义和使用结构体变量 (1).结构体的定义 C语言允许用户自己建立由不同类型数据组成的组合型的数据结构,它称为结构体. (2).声明一个结构体类型的一般形式为: ...
- linux的c文件报错for,linux c 编译错误 conflicting types for 的解决办法
程序在Windows下运行是OK的,但是放在linux系统gcc编译就会报错. 报错如下: tongxunlu.c:6:1: error: unknown type name 'linkman' li ...
- Linux下MySQL登录报错1045,linux下 root 登录 MySQL 报错的问题
最近在centos 7上,通过yum安装了mysql,安装成功后,使用root登录,出现了如下报错: error 1045 (28000): access denied for user 'root' ...
- linux编译CH340驱动报错,CH340 Linux驱动使用教程
CH340 Linux驱动使用教程 在官方Linux内核版本中自Kernel2.6以后就默认包含了对CH340/CH341芯片的驱动支持了,但比较遗憾的是该自带驱动版本较老(由开源社区开发者提交)已不 ...
- _C语言_结构体_vistodio_c报错.+初学者的自闭瞬间。哎。
在C语言中一直用不好子函数, 前几天看书+视频教学终于弄懂了, 想着用大一上做到的课设重新打一遍 工资纳税系统(不能说是系统就是一个控制台窗口连程序都算不上哈哈哈但是当时做出来的时候真的就是蛮高兴地) ...
- linux安装python库报错pywin32,Linux windows安装paramiko模块
1.首先我们刚刚说的pip是什么? 在pip的python官网上我们可以看到,pip 是"A tool for installing and managing Python packages ...
- linux结构体转qbytearray,QByteArray储存二进制数据(包括结构体,自定义QT对象)
因为利用QByteArray可以很方便的利用其API对内存数据进行访问和修改, 构建数据库blob字段时必不可少; 那如何向blob内写入自定义的结构体和类 //自定义person结构体 typede ...
- java结构体构建学生 学号_易错题: 程序通过定义学生结构体变量,存储了学生的学号、姓名和3门课的成绩。...
根据网考网考试中心的统计分析,以下试题在2015-12-7日计算机二级考试C语言习题练习中,答错率较高,为:93% [填空题] 程序通过定义学生结构体变量,存储了学生的学号.姓名和3门课的成绩.所有学 ...
- Linux下Tomcat启动报错:port already in use
Linux下Tomcat启动报错:port already in use,导致该问题的原因很多,我在这里记录一下我遇到的情况的解决办法. 检查了${TOMCAT_HOME}/conf/server.x ...
最新文章
- matlab 数据集制作,机器学习数据集制作与划分MATLAB实现
- 斯坦福2019 AI年度报告出炉 - 700亿美元投入AI
- 一文看透全球光伏“大跃进”发展历程
- python求列表最大值下标_切片,丝滑的字符串 | Python基础连载(三)
- C++提高部分_C++函数模板_基本用法---C++语言工作笔记081
- 使用EDITPLUS编写C#控制台应用程序
- 为什么不要把ZooKeeper用于服务发现
- arXiv上引用文章在bibtex下的引用格式
- QT实现经纬度转换为图片像素坐标
- 22fall 游戏/数字媒体/人机交互DIY留学申请经验贴
- Virtex-4 cameralink开发板PCI图像采集卡定制FPGA-HDMI编码-LVDS相机
- 优秀广告设计作品常用的几大设计思维
- pandas 处理缺失值[dropna、drop、fillna]
- BZOJ1296(SCOI2009)[粉刷匠]--背包+DP
- Linux 视频剪辑与录音
- python爬取股票平均成本怎么算_Python-多个股票的投资组合分析,对,进行
- 插件 - 收藏集 - 掘金
- 字体包和字体子集制作,位图字体制作工具推荐
- 网络学习笔记之IP地址
- 如何按签收时间筛选快递单号并导出
热门文章
- 使用 TypeScript 自定义装饰器给类的方法增添监听器 Listener
- Angular jasmine单元测试框架里describe的实现原理
- Angular里的特殊字符ɵ和ABAP变量名里的特殊字符*
- Angulary应用依赖里的zone.js
- 一文让您搞清楚@Resources, @Inject和@Autowired的区别
- role cache - set data user parameter - /UI2/CACHE_DISABLE
- when is SAP UI5 url hash changed in browser
- Fiori as a Service - FaaS - Creation of inline task option is not available
- 我回答的一个粉丝关于模拟SAP事务的问题
- javascript file cached in server side