2012-07-26 118 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