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模式设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怪物猎人世界解禁后干嘛
- 下一篇: wordpress linux位置,Li