简体   繁体   中英

use of macro container_of with struct member

I am trying to understand some proprietary code in which container_of is called with single parameter which is a member struct of the return struct.

struct want{
.
.
struct member_used;
};
member_struct *ptr_member_used;
struct want *ret_struct container_of(ptr_member_used);

i checked following links

http://codinghighway.com/2013/08/10/the-magical-container-of-macro-and-its-use-in-the-linux-kernel/

Doubts regarding container_of macro in linux

Understanding container_of macro in the Linux kernel

When do you use container_of macro?

but all these links are using three parameters but none of them is using struct member to retrieve corresponding struct.

My worry here is how container_of macro returns corresponding struct just by passing struct member?

program is running correctly on 64 bit ubuntu 14.0.4 with kernel 3.13.0 and gcc 4.8.4

There is another definition of container_of somewhere in the sources used to build proprietary code. That another definition can be macro or function and take one argument. There is nothing more I can say about it. You should find it in the headers or sources.

container_of macro basically used to obtain the parent structure address from any of it's member.

In definition of the macro 1st line is determining type of the member and second line calculating offset between structure start to the member from which we are determining the struct start point.

Refer to below code for clear understanding, it's simple:

#include <stdio.h>
#include <stddef.h>

// Copied from linux/kernel.h
#define container_of(ptr, type, member) ({                      \
                const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
                (type *)( (char *)__mptr - offsetof(type,member) );})

struct myStruct { int a, b; };

int main()
{
    struct myStruct var = {.a = 0, .b = 0}; 

    int *memberPointer = &var.b;

    printf("Struct addr=%p\n", &var);

    struct myStruct *newSp = container_of(memberPointer, struct myStruct, b); 

    printf("Struct addr new=%p\n", newSp);

    if(newSp == &var)
    {   
        printf("It's equal.\n");
    }   

    return 0;
}

Output:

Struct addr=0x7ffddcfd2b10
Struct addr new=0x7ffddcfd2b10
It's equal.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM