리눅스 커널과 윈도우 커널을 비교하는 질문을 읽다가 생각난 건데.

리눅스 커널 코드에 보이는 container_of 매크로를 아시는 분?

같은 기능의 매크로가 윈도우 커널에서는 CONTAINING_RECORD 매크로로 제공되고 있습니다.


struct full_struct {

    int a;

    char b[60];

    int c;    

};


이런 형태의 구조체 struct full_struct 가 있다고 할 때,

예를 들어 어떤 포인터 값 char *ptr를 알고 있다고 해 보겠습니다.

이 포인터는 char [60] 배열의 시작 주소를 가리키는 포인터인데, 그냥 배열이 아니라

struct full_struct 안에 들어있는 배열을 가리키는 것입니다.


이 때 이 포인터로부터 struct full_struct * 포인터를 구하고 싶으면?

이런 경우에 container_of 매크로를 사용합니다. (윈도우 커널에서는 CONTAINING_RECORD라는 매크로로 제공됨)


#define container_of(ptr, type, member) ({ \\

                const typeof( ((type *)0)->member ) *__mptr = (ptr); \\

                (type *)( (char *)__mptr - offsetof(type,member) );})


(offsetof는 stddef.h 안에 제공되는 표준 라이브러리 매크로)


위와 같이 정의되어 있는데요.


struct full_struct *ptr_stru;

// ...

ptr_stru = container_of(ptr, struct full_struct, b);


식으로 struct full_struct 포인터를 구할 수 있습니다.


커널 개발 안 해 보신 분은 모르실 수도 있을 것 같아서 올려 봅니다~

주로 저 매크로는 전체 구조체 내에 들어있는 연결 리스트 구조체(연결 리스트 구조체끼리 연결되어 있음)의 포인터로

전체 구조체 포인터를 구할 때에 많이 쓰여요.