2013年10月2日 星期三

container_of用法

container_of 在kernel下 include/linux/kernel.h下 (不是很好懂就是了= =)
但至少要會用
在另一个地方,获得了变量demo中的某一个域成员变量的指针,比如:
      type3  *memp = get_member_pointer_from_somewhere();
此时,如果需要获取指向整个结构体变量的指针,而不仅仅只是其某一个域成员变量的指针,
我们就可以这么做:
     struct demo_struct *demop = container_of(memp, struct demo_struct, member3);
这样,我们就通过一个结构体变量的一个域成员变量的指针获得了整个结构体变量的指针。
大置上就是這樣用 :)
ref: Here
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define offsetof(TYPE,MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
#define container_of(ptr,type,member)({ \
const typeof(((type *)0)->member)* _mptr=(ptr); \
(type *)((char *)_mptr-offsetof(type,member));})

struct test
{
    int i;
    char *ch;
    int k;
};

int otherfun (int *intk)
{
    struct test *test1=container_of(intk, struct test, k);  //通过结构变量的一个成员指针获得了整个结构的指针
    printf("test1i=%d\n", test1->i);
    printf("test1j=%s\n", test1->ch);
    printf("test1k=%d\n", test1->k);

    printf("&test1=%p\n", &test1);
    printf("&test1i=%p\n", &test1->i);
    printf("&test1ch=%p\n", &test1->ch);
    printf("&test1k=%p\n", &test1->k);

    return 1;
}

int main (void)
{
    struct test temp={11,"",33};
    temp.ch=malloc(sizeof(char)*4);
    strncpy(temp.ch, "gogo",sizeof(char)*4);
    int *kk= &temp.k;
    otherfun(kk);
    printf("&temp=%p\n", &temp);
    printf("&tempi=%p\n", &temp.i);
    printf("&tempch=%p\n", &temp.ch);
    printf("&tempk=%p\n", &temp.k);
    return 0;
}
outpur:
test1i=3
test1j=gogo
test1k=3
&test1=0x7fff34995ce0
&test1i=0x7fff34995d10  // addr i相同
&test1ch=0x7fff34995d18  // addr ch相同
&test1k=0x7fff34995d20  // addr k相同
&temp=0x7fff34995d10
&tempi=0x7fff34995d10  // addr i相同
&tempch=0x7fff34995d18  // addr ch相同
&tempk=0x7fff34995d20  // addr k相同

container_of 跟link list有很大關,beter的博客大大寫的很好懂 :)
(keyword: 内核数据结构之双向循环链表,這樣link壞了還能用google找 XD)

other ref:
揭开linux内核中container_of的神秘面纱
ADRIAN'S BLOG

沒有留言:

張貼留言