简体   繁体   中英

How to retrieve the structure holding a pointer with container_of macro

I'm using the macro container_of defined as:

#define container_of(ptr, type, member) ((type *)((char *)(1 ? (ptr) : &((type *)0)->member) - offsetof(type, member)))

the structure vector:

struct vector {
    uint32_t signature;
    size_t element_size;
    size_t size;
    void *data;
};

And finally the function vectorSize receiving a pointer to some data . This function is not working because only the data member inside struct vector v have the right value, the others have garbage, resulting in failing the if statement SIGNATURE.

size_t vectorSize(void *vec)
{
    void **pdata = &vec;
    struct vector *v = container_of(pdata, struct vector, data);

    if (v->signature != VECTOR_SIGNATURE) return 0;
    return v->size;
}

What is wrong with my setup?

First of all, please don't post code like 1 ? this : that 1 ? this : that . I know, this is experimental code from you whilst digging into the problem. But it shouldn't posted here as it confuses us.

If I understood you right, your function receives a pointer to a struct member and you need a macro delivering the container struct. Try this:

#define CONTAINER_OF(MemberPtr, StrucType, MemberName) ((StrucType*)( (char*)(MemberPtr) - offsetof(StrucType, MemberName)))

Followed by:

size_t vectorSize(void *vec)
{
    struct vector *v = CONTAINER_OF(vec, struct vector, data);

    if (v->signature != VECTOR_SIGNATURE) return 0;
    return v->size;
}

Example usage of the container_of macro:

struct vector *vector_of(void* element) 
{
    return container_of(element, struct vector, data);
}

For your implementation, it seems to me it should look like this:

size_t vector_size(void *vec_ptr)
{
    struct vector *vec = v_ptr;
    return vec->signature != VECTOR_SIGNATURE ? 0 : vec->size;
}

Since data is of type (void *), vec needs to be of (void **). But you should not give the address of vec. Instead, just cast it as a (void **). Like below:

struct vector *v = container_of((void **)vec, struct vector, data);

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