如何从 C 中的成员访问包含结构?
How to access containing structure from a member in C?
我正在使用一些内核模块 (4.19.97),我分配 struct my_sock
如下所示。
struct my_target {
union thingA { ... } a;
struct thingB *b;
};
struct my_sock {
struct sock sk;
// ...
struct my_target target;
};
struct my_sock *my_s;
my_s = my_sock_alloc();
// ...
my_s->sk.sk_prot->init(sk);
上面调用了这个回调。
static int my_init(struct sock *sk)
{
// I do the following because I cannot pass in the allocated
// `struct my_sock` into this function.
struct my_sock *ms = my_sk(sk);
// I want to access my_s->my_target or any field within
// `struct my_target` here, but at this point, `ms` is
// pointing to the the first member of `struct my_sock`, and
// not the originally allocated `my_s`.
ms->target.a;
}
static inline struct my_sock* my_sk(const struct sock *s)
{
return container_of(s, struct my_sock, sk);
}
// Here's how my_s gets allocated. Note that this is not the same
// structure as the first member of `struct my_sock`.
struct my_sock* my_sock_alloc(void)
{
struct my_sock *sk = NULL;
sk = kmem_cache_zalloc(my_sk_cachep, GFP_KERNEL);
if (!sk)
return NULL;
return sk;
}
这就是问题所在。根据评论,内核在 include/linux/kernel.h
中具有 container_of
的代码,其中 casts a member of a structure out to the containing structure
。
当我使用my_sk(sk)
时,我得到了包含结构的第一个成员的指针地址。问题是这与我在第一行分配的 my_s
不同,我需要指向 my_s
的指针才能访问 target
成员。
关于我如何在调用 my_init()
中访问 my_s->target
的想法(而不是全局化)?
由于 sk
是 struct my_sock
中的第一个字段,您只需转换指针即可,一切正常:
struct my_sock *ms = (struct my_sock *)sk;
仅当“基础”结构不是第一个字段时才需要在container_of中完成的额外工作。
我正在使用一些内核模块 (4.19.97),我分配 struct my_sock
如下所示。
struct my_target {
union thingA { ... } a;
struct thingB *b;
};
struct my_sock {
struct sock sk;
// ...
struct my_target target;
};
struct my_sock *my_s;
my_s = my_sock_alloc();
// ...
my_s->sk.sk_prot->init(sk);
上面调用了这个回调。
static int my_init(struct sock *sk)
{
// I do the following because I cannot pass in the allocated
// `struct my_sock` into this function.
struct my_sock *ms = my_sk(sk);
// I want to access my_s->my_target or any field within
// `struct my_target` here, but at this point, `ms` is
// pointing to the the first member of `struct my_sock`, and
// not the originally allocated `my_s`.
ms->target.a;
}
static inline struct my_sock* my_sk(const struct sock *s)
{
return container_of(s, struct my_sock, sk);
}
// Here's how my_s gets allocated. Note that this is not the same
// structure as the first member of `struct my_sock`.
struct my_sock* my_sock_alloc(void)
{
struct my_sock *sk = NULL;
sk = kmem_cache_zalloc(my_sk_cachep, GFP_KERNEL);
if (!sk)
return NULL;
return sk;
}
这就是问题所在。根据评论,内核在 include/linux/kernel.h
中具有 container_of
的代码,其中 casts a member of a structure out to the containing structure
。
当我使用my_sk(sk)
时,我得到了包含结构的第一个成员的指针地址。问题是这与我在第一行分配的 my_s
不同,我需要指向 my_s
的指针才能访问 target
成员。
关于我如何在调用 my_init()
中访问 my_s->target
的想法(而不是全局化)?
由于 sk
是 struct my_sock
中的第一个字段,您只需转换指针即可,一切正常:
struct my_sock *ms = (struct my_sock *)sk;
仅当“基础”结构不是第一个字段时才需要在container_of中完成的额外工作。