1. 前言:一个结构体的启示
作为一名在Linux驱动开发领域摸爬滚打多年的工程师,我至今记得第一次完整阅读platform_driver结构体定义时的震撼。这个看似普通的C语言结构体,竟然完美诠释了面向对象编程的三大核心特性:封装、继承和多态。在Linux内核这个纯C语言构建的庞然大物中,面向对象思想无处不在,而驱动子系统正是这种思想的集大成者。
让我们先解剖这个经典的platform_driver结构体(基于Linux 5.x内核):
c复制struct platform_driver {
int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
void (*shutdown)(struct platform_device *);
int (*suspend)(struct platform_device *, pm_message_t state);
int (*resume)(struct platform_device *);
struct device_driver driver;
const struct platform_device_id *id_table;
};
这个结构体最精妙之处在于:
- 它将设备驱动的基本操作(probe/remove等)封装在一起
- 通过嵌套
device_driver实现了继承关系 - 通过函数指针实现了运行时多态
关键理解:Linux内核开发者用C语言实现了其他语言内置的面向对象机制,这种设计既保持了C的高效,又获得了面向对象的灵活性。
2. 封装:驱动对象的"黑匣子"设计
2.1 数据与行为的统一封装
在典型的面向对象语言中,类将数据和方法绑定在一起。C语言通过结构体+函数指针实现了同样的效果。以字符设备驱动为例:
c复制struct my_char_device {
struct cdev cdev; // 内核字符设备结构
unsigned char *buffer; // 设备缓冲区
int buffer_size; // 缓冲区大小
struct mutex lock; // 互斥锁
// 操作方法
int (*open)(struct inode *, struct file *);
ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
};
这种封装带来了几个实际好处:
- 相关数据和操作自然聚合
- 减少了全局变量的使用
- 提高了代码的可读性和可维护性
2.2 信息隐藏的实现
面向对象的重要特性是隐藏内部实现细节。Linux驱动通过以下方式实现:
- 不透明指针:驱动对外只暴露结构体指针,内部成员对外不可见
c复制typedef st
