Linux内核C语言中的面向对象

  • 转载自”Blog of UnicornX” (http://unicornx.github.io/)

  • 面向对象的思想在c语言中的应用,第一次看到才知道c语言还能这么用。。。


前言

  • 语言只是工具,重要的是思想。但是!!C语言用面向对象??看了内核代码,真给那些写Linux、内核的大神跪了。。。
  • 当然因为C语言的局限性,并非完全面向对象的实现,私有成员等就没有了。

封装

  • 既类在C语言中的实现,实际上是 struct + 函数体 = 函数表
    结构体里不允许存在成员函数,但是换成指向函数的指针是可以滴。

  • 示例

    1
    2
    3
    4
    5
    struct foo_operations {
    void (*op_a) (struct foo *, loff_t, int);
    void (*op_b) (struct foo *, char __user *, size_t, loff_t *);
    void (*op_c) (struct foo *, const char __user *, size_t, loff_t *);
    };

继承

  • 这个简单点, struct 里面套 struct ,警告熟悉c语言的应该都清除。。。这里没有父类子类的严格区分,实际上是完全自由的。

  • 示例

    1
    2
    3
    4
    5
    6
    struct foo {
    int a;
    int b;
    int c;
    struct foo_operations ops;
    };

多态

  • 这个是最有意思的,c语言中严格规定同一个.c文件/工程中不能存在重名函数,但是c语言的精华-指针给了思路,借助结构体,我函数名不变,每指向不同的结构体变量就行了。。。虽然还是很麻烦。。

  • 示例

    1
    2
    3
    4
    5
    6
    struct foo a;
    a->ops = ops1;
    a->ops->op_a(a);
    //切换
    a->ops = ops2;
    a->ops->op_a(a);

链表

  • 内核内大量运用链表,开始不清楚真是头晕。。

  • 示例

    1
    2
    3
    struct list_head {
    struct list_head *next, *prev;
    };

    一个指向自身的结构体,包含下一个与自身的指针。
    使用

    1
    2
    3
    4
    struct A_LIST {
    data_t data;
    struct list_head *list;
    };
  • offsetof宏

    1
    #define offsetof(type, member) (size_t)&(((type*)0)->member)

    offsetof是用来判断结构体中成员的偏移位置

  • container_of_宏

    1
    2
    3
    #define container_of(ptr, type, member) ({ \
    const typeof( ((type *)0)->member ) *__mptr = (ptr); \
    (type *)( (char *)__mptr - offsetof(type,member) );})

    根据一个结构体变量中的一个域成员变量的指针来获取指向整个结构体变量的指针..链表元素常用