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

offsetof() of nested C struct in C++

本文关键字:offsetof 结构 嵌套 C++      更新时间:2023-10-16

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

结构proc_event{。。。活接头{。。。结构fork_proc_event{__kernel_pid_t parent_pid;。。。}叉子;。。。}事件数据;。。。}

在C中,我会这样做:

int off = offsetof(struct fork_proc_event, parent_pid);

不过我是用C++开发的。如果我尝试这样做:

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

我得到以下错误:

错误:需要类型说明符错误:应为","错误:在","标记之前应为")"

offsetof()行应该是什么样子?

思考offsetof宏的实现方式可能会有所帮助。这里有一个例子:

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

换句话说,使用0作为指向您感兴趣的类型的指针,只需获取结构字段的地址。。。

因此,如果你想要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)

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

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

然后您就可以在C++代码中的offsetof中将其称为proc_event::whatever::fork_proc_event

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

如果你对parent_pidproc_event开始的偏移感兴趣,你可以做

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

如果不能更改声明,可以通过计算fork_proc_eventparent_pid的偏移量

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

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