参照元†
- ポインタが指す構造体のメンバ、それを含む構造体へのポインタを返す。
- 例えば、
struct example {
int mem_a;
char mem_b;
};
struct example hoge;
- このような構造体があったとき、
int *mem_ptr = &hoge.mem_a;
- 構造体のメンバへのポインタmem_ptrしか分からない状態からhogeへのポインタを得たいときにcontainer_ofを使う。
struct example *ptr = container_of(mem_ptr, struct example, mem_a);
- するとptrが指す先(hoge.mem_a)を含む構造体へのポインタ(&hoge)が得られる。
- ptr
- type
- ptrに指定したポインタが指すメンバ、これを含む「構造体名」を指定する。マクロはここで指定した型のポインタを返す。
- 上記の例で言うと変数名のhogeではなくて、変数の型の名前struct exampleを指定する。
- member
- ptrに指定したポインタが指す「メンバ名」を指定する。
- typeに指定した型はmemberに指定した名前のメンバを持っていないとコンパイルエラーになる。
- 上記の例で言うとポインタ変数mem_ptrではなく、struct example構造体のメンバ名であるmem_aを指定する。
返り値†
- type *
- 指定した構造体のメンバへのポインタ(ptrに指定する)が指すメンバ(メンバの名前はmemberに指定する)、これを含む構造体(構造体の型はtypeに指定する)へのポインタを返す。
- 例えばlist_entry(a, struct hogehoge, b) とすれば、struct hogehoge *が返ってくる。
/**
* 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); \
- ポインタ演算のためvoid *型の__mptrに変換する。
BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \
!__same_type(*(ptr), void), \
"pointer type mismatch in container_of()"); \
- ptrは、typeのmemberのポインタ型か、void *である必要がある。そうでなければビルドエラーにする。
((type *)(__mptr - offsetof(type, member))); })
- 構造体の先頭へのポインタを計算する。この値がマクロの戻り値となる。
コメント†