C ++中嵌套C结构的offsetof()

时间:2012-07-26 07:10:45

标签: c++ c sockets struct offsetof

我正在尝试在C ++(Linux)中为我的一个套接字添加套接字过滤器。在套接字过滤器中,我需要获取 struct fork_proc_event 的偏移量,它嵌套在另一个结构中。定义如下(cn_proc.h):

struct proc_event {
    ...
    union {
        ...
        struct fork_proc_event {
            __kernel_pid_t parent_pid;
            ...
        } fork;
        ...
    } event_data;
    ...
};

在C中我会这样做:

int off = offsetof(struct fork_proc_event, parent_pid);

但是我正在用C ++开发。如果我尝试这样做:

int off = offsetof(proc_event::fork_proc_event, parent_pid);

我收到以下错误:

error: expected type-specifier
error: expected `,'
error: expected `)' before ',' token

offsetof()行应该如何?

2 个答案:

答案 0 :(得分:5)

考虑如何实现offsetof宏可能会有所帮助。这是一个例子:

#define offsetof(TYPE, MEMBER) \
    ((uintptr_t)&(((TYPE*)0)->MEMBER))

换句话说,使用0作为指向您感兴趣的类型的指针,并简单地获取struct字段的地址......

所以如果你想要parent_pid相对于fork的偏移量(这是我最初解析你的问题的方式):

((char*)&((struct proc_event*)0)->event_data.fork.parent_pid) - ((char*)&((struct proc_event*)0)->event_data.fork)

在第二次阅读时,您可能只想要parent_pid相对于struct proc_event开头的偏移量。调整上面的例子:

((uintptr_t)&((struct proc_event*)0)->event_data.fork.parent_pid)

答案 1 :(得分:3)

我并不完全理解所有这些黑客的必要性,当你所要做的就是给你的嵌套union类型命名。任何名称,只是为了能够在C ++代码中引用它

struct proc_event {
    ...
    union whatever {
        ...
        struct fork_proc_event {
            __kernel_pid_t parent_pid;
            ...
        } fork;
        ...
    } event_data;
    ...
};

然后,您将能够在{C ++代码中的proc_event::whatever::fork_proc_event中将其称为offsetof

size_t off = offsetof(proc_event::whatever::fork_proc_event, parent_pid);

如果您对从parent_pid开始的proc_event偏移感兴趣,可以

size_t off = offsetof(proc_event, event_data.fork.parent_pid);

如果您无法更改声明,可以通过

计算parent_pidfork_proc_event内的偏移量
size_t off = 
  offsetof(proc_event, event_data.fork.parent_pid) - 
  offsetof(proc_event, event_data.fork);

(虽然我不能马上说明最后两个是offsetof使用的正式合法例子,但它们通常在实践中没有任何问题。)