2012-07-26 124 views
0

我想在C++(Linux)中为我的某个套接字添加一个套接字过滤器。在套接字过滤器中,我需要获得struct fork_proc_event的偏移量,它嵌套在另一个结构中。该定义是这样的(cn_proc.h):在C++中嵌套C结构的offsetof()

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()线是什么样子?

+0

刚通过查找:它可以是'proc_event :: fork :: fork_proc_event'? – Alex 2012-07-26 07:13:03

+0

不,它不起作用。我已经尝试过了。不管怎么说,还是要谢谢你。 – 2012-07-26 07:21:20

+0

也许:offsetof(struct proc_event,event_data.fork。parent_pid) - offsetof(struct proc_event,event_data.fork) – 2012-07-26 07:38:24

回答

5

这可能有助于思考一个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相对于的开始。适应上面的例子是:

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

谢谢,但: 错误:'struct proc_event'没有名为'fork'的成员 – 2012-07-26 07:20:02

+0

@VíctorFernández - 是的,我没有注意到'event_data'最初。请刷新。我正在编辑与其他内容的答案。 – asveikau 2012-07-26 07:21:27

+0

指针大小(除了某些函数指针)是相同的。将指针转换为char *或uintptr_t而不需要解引用它只会使代码更难读取IMO。这是有原因的吗? – 2012-07-26 07:23:52

2

我不完全理解所有这些黑客的需要,当所有你需要做的就是你的嵌套union类型提供一个名称。任何名称,只是为了能够引用它在C++代码

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

然后你就可以把它称为proc_event::whatever::fork_proc_eventoffsetof在C++代码

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

如果您有兴趣从proc_event开始的parent_pid偏移,你可以做

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

如果你不能改变的声明,你可以计算出关通过做

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

一套parent_pidfork_proc_event(虽然我不能说马上过去两年是否offsetof使用的正式法律的例子,他们通常会在实际工作中没有任何问题。)

+0

@VíctorFernández:我在答案中也介绍了这个案例。 – AnT 2012-07-26 07:46:06

+0

感谢您的回答。 – 2012-07-26 07:59:38