2

C ++(Linux)のソケットの1つにソケットフィルターを追加しようとしています。ソケットフィルターでは、別の構造内にネストされているstructfork_proc_eventのオフセットを取得する必要があります。定義は次のようになります(cn_proc.h):

struct proc_event {
    ..。
    ユニオン{
        ..。
        struct fork_proc_event {
            __kernel_pid_t parent_pid;
            ..。
        } フォーク;
        ..。
    } event_data;
    ..。
};

CIではこれを行います:

int off = offsetof(struct fork_proc_event, parent_pid);

ただし、私はC++で開発しています。私がこれをやろうとすると:

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

次のエラーが発生します。

エラー:予期されるタイプ指定子
エラー:予期される `、'
エラー:「、」トークンの前に「)」が必要です

offsetof()行はどのように見えるべきですか?

4

2 に答える 2

5

offsetofマクロの実装がどのように行われるかを考えると役立つ場合があります。これが1つの例です:

#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_pid2回目の読み取りでは、の先頭を基準にしたオフセットが必要な場合がありstruct proc_eventます。上記の例を適応させると、次のようになります。

((uintptr_t)&((struct proc_event*)0)->event_data.fork.parent_pid)
于 2012-07-26T07:13:51.050 に答える
4

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_pid内部のオフセットを計算できます。fork_proc_event

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

(最後の2つが正式に合法的な使用例であるかどうかはすぐにはわかりませんがoffsetof、通常は問題なく実際に機能します。)

于 2012-07-26T07:28:27.977 に答える