介紹
此 marco 最主要的作用是
你只要傳給他某個 struct 中的 member 的 pointer
他會幫你算出此 struct 的起始位置
也就是說你就可以知道其他 member 的位置並存取
舉例
以下是還沒使用 container_of
先在 main 建立 person 變數,之後使用 print_info 印出 phone_num
如果你目前只能修改 print_info,要如何印出其他 member 的值?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| typedef struct person { char name[16]; char phone_num[16]; int id; int year; }stPerson, *stPerson_ptr;
void print_info(char * phone) { printf("Phone num: %s \n",phone); return; }
int main(void) { stPerson_ptr pJason = malloc( sizeof(stPerson)); strncpy( pJason->name, "Jason", sizeof(pJason->name)); strncpy( pJason->phone_num, "0955123456", sizeof(pJason->phone_num)); pJason->id = 112233; pJason->year = 28;
print_info(pJason->phone_num); return 0; }
|
使用 container_of
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| #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 person { char name[16]; char phone_num[16]; int id; int year; }stPerson, *stPerson_ptr;
void print_info(char * phone) { /* 關鍵是使用 container_of,需要傳入 3 個參數 1. struct 中的某個 member pointer 2. struct 名稱 3. 此 member 在 struct 中的名稱 */ stPerson_ptr pPerson = container_of( phone, stPerson, phone_num );
printf("Name : %s \n",pPerson->name); printf("Phone num : %s \n",pPerson->phone_num); printf("ID : %d \n",pPerson->id); printf("Year : %d \n",pPerson->year); return; }
int main(void) { stPerson_ptr pJason = malloc( sizeof(stPerson)); strncpy( pJason->name, "Jason", sizeof(pJason->name)); strncpy( pJason->phone_num, "0955123456", sizeof(pJason->phone_num)); pJason->id = 112233; pJason->year = 28;
print_info(pJason->phone_num); return 0; }
|
參考
非常詳細的介紹