Linux 内核的面向对象设计思想

2023-05-16

使用C语言实现面向对象设计的方法


Linux内核用C语言实现了面向对象的设计思想。即使用了三方面的特性:封装、继承、多态。

使用结构体实现了对对象的封装;某一结构体成员中含有其他结构体的实例,实现了一个结构体对另一个结构体的继承;使用成员函数指针的结构体,通过对该结构体中同一个函数指针赋不同的值,调用同一个成员,实际上就会调用不同的函数,实现多态

结构体中的参数中有一个参数是指向这个结构体的指针,相当于this指针。使用C语言模拟面向对象的设计机制,使程序员方便对对象的构造、析构、拷贝、赋值等操作。

类的多态特征是linux内核经常用到的。例如在驱动代码中使用函数指针来定义一组设备操作函数,从而模拟了多态的特点。

1、封装

封装就是把一个抽象的事物的属性和属性的操作方法打包在一起,外界的模块只能通过这个抽象事物对外提供的函数接口,对其属性进行访问。在C++或其他高级语言中,封装通常被称作“类”。而 C 语言一般使用结构体对事物进行封装。

使用结构体可以很好地对数据进行封装,并且需要通过指定的操作函数对结构体内的数据进行访问。

每个操作函数的第一个参数是对象本身的指针,通过这个指针去访问具体对象里面的属性。这是因为在 C 语言中不存在像 C++ 语言那样的 this 指针,所以我们只能显式地通过函数传参的方式,让函数内部可以访问对象实例的其他成员。

2、继承

继承就是基于一个已有的类(一般称作父类或基类),再去重新声明或创建一个新的类,这个类可以称为子类或派生类。子类或派生类可以访问父类的数据和函数,然后子类里面又添加了自己的属性和数据。在 C 语言里面,可以通过结构体嵌套的方式去实现类的单继承(暂不考虑多重继承),但有一点注意事项,就是在结构体嵌套时,父类对象需要放在结构体成员的第一个位置。

3、多态

在C++中,多态是通过动态绑定实现的,程序在运行的时候,基类会通过虚函数表来查找子类的多态函数实现,在Linux内核中,模拟多态的方法要简单一些,实际上是在基类的函数方法中,通过获取子类对象,再嵌套调用子类对象的同名函数来实现的。

举例

file_operations 很好地展示了结构体如何使用这种机制来定义一组文件操作的方式。用这种方式,Linux很好地贯彻了所有的设备都是文件这种概念。不同的设备可以有不同的处理函数,但使用相同的接口(read,write…),这样就把底层设备的差异在文件系统这一层隔离开来。

在Linux内核设备驱动中,在用户态open一个字符设备,然后调用字符设备的read、write、等函数,最终也会调用到内核态设备驱动程序相应的read、write函数的实现,从而模拟了通过基类与多态函数的特性来访问子类的目的。

实际上,Linux内核会维护基类与子类cdev对象实例的链表,当用户态发起read/write/ioctl等字符设备系统调用函数时,read/write/ioctl等字符设备系统调用函数会通过/dev/*下的字符设备,设备节点号的方式(主节点号major,次节点号minor)从cdev链表的子类中,找到对应子类的cdev对象实例,然后判断是否为空并调用子类cdev->ops->read/write/ioctl等实际子类的多态函数实现,从而最终实现了通过访问基类的多态函数,最终访问到子类实际的多态函数,这个面向对象的特性。

struct file_operations 
{
	struct module *owner;
	loff_t (*llseek) (struct file *, loff_t, int);
	ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
	ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
    ......
};

Linux内核中也经常用到类的继承关系。这种关系使用C也很容易模拟,就是使用结构体嵌套(platform_device中嵌套了device )。但是不能直接引用。也不能通过基类访问子类,但是可以通过一个宏定义(container_of(ptr, type, member))来访问。

struct platform_device 
{
	const char	* name;
	int	 id;
	struct device dev;
	u32	 num_resources;
	struct resource	* resource;
	const struct platform_device_id	*id_entry;
	/* arch specific additions */
	struct pdev_archdata	archdata;
};


通过基类访问子类的方法

在面向对象编程中,通过继承关系,我们将子类对象赋值给基类对象的时候,可以通过基类对象,调用多态函数访问子类对象的实际函数。


驱动和设备匹配

总线对设备和驱动进行匹配probe,首先是对某个驱动或设备链表进行遍历(mach),然后一一匹配。Linux使用总线的概念来管理设备与驱动。在某种具体的总线上,挂着同种类的设备与驱动。从内核视角来看,想找某种设备,就从具体的某个总线上寻找,然后遍历这条总线。

添加一个设备,主要的工作是初始化设备结构体,并把它添加到对应的总线上去。在总线上将去匹配挂在该总线上的驱动。

… … … … … …

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux 内核的面向对象设计思想 的相关文章

  • ArduPilot之开源代码调试技巧

    ArduPilot之开源代码调试技巧 1 源由2 ArduPilot Code Debugging Part13 ArduPilot Code Debugging Part24 持续更新中 5 参考资料 1 源由 对于如何调试和验证Ardu
  • ArduPilot飞控启动&运行过程简介

    ArduPilot飞控启动 amp 运行过程简介 1 源由2 Copter飞控2 1 入口2 3 运行 main loop 3 Ardunio编程3 1 setup AP Vehicle setup3 2 loop AP Vehicle l
  • WIN7 64位系统 CDC类 虚拟串口驱动无法安装的解决办法

    最近用STM32装个USB转虚拟串口 xff0c 但是驱动怎么也安装不上 百度了一些网页 xff0c 方法很多 xff0c 但是我这里按如下步骤处理 xff1a 首先 xff0c 确保C Windows System32 drivers u
  • ubuntu桌面版打开终端Terminal的几种方法

    1 Ctrl 43 Alt 43 T 快捷键直接打开 2 在Ubuntu左上角选择File Open in Terminal 3 快捷键alt 43 F2调出Run a Command xff0c 输入gnome terminal 4 添加
  • 什么是对称加密(对称加密简介)

    什么是对称加密 1 什么是对称加密2 编码3 加密算法3 1 DES3 1 1 什么是DES3 1 2 加密和解密 4 3DES4 3 1 什么是3DES4 3 2 3DES加密解密 5 AES5 1 什么是AES5 2 AES加密解密 1
  • Linux应用程序之Helloworld入门

    对于初学者来说 xff08 本人就是 xff09 xff0c 如何开始写第一个程序至关重要 有的时候一个简单的问题会严重影响到学习的积极性和自信心 这里结合实际工作中的一些经验 xff0c 总结方法步骤 xff0c 对Linux下应用程序H
  • ctags简明使用方法

    ctags xff08 Generate tag files for source code xff09 是vim下方便代码阅读的工具 xff0c 它可以在命令行下帮助程序员很容易地浏览源代码 ctags 最先是用来生成C代码的tags文件
  • char和unsigned char强制转换成int后的差异

    最近有人提到char和unsigned char有什么区别 xff0c 当然这个问题如果刚学计算机或者编程语言的人来说 xff0c 非常简单 我也这么认为 xff0c 无非就是有符号和无符号的差别嘛 这个问题让我想到了以前学习计算机常识的时
  • 如何使用mstsc进行远程登录?

    如何使用mstsc进行远程登录 xff1f 步骤一 xff1a 点击 开始 gt 运行 xff0c 输入mstsc xff0c 如下图所示 xff1a 步骤二 xff1a 输入连接PC的IP地址 xff0c 如下图所示 xff1a 步骤三
  • VNC远程ubuntu时,右击无法打开terminal

    参考博客 xff1a https blog csdn net qq 44132116 article details 103960393 问题描述 xff1a 我通过命令行连接实验室服务器 xff0c 装了anaconda xff0c 之后
  • TCP实时传图像

    目的 xff1a QT 43 openCV xff0c 在Ubuntu16 04版本下 xff0c 通过TCP实现图片的传输 步骤 xff1a 客户端建一个相机线程 xff0c 一个TCP线程 xff0c 相机线程捕获画面并将Mat传到TC
  • Ubuntu mate 16.04安装ROS

    官方文档有详细的安装步骤 xff1a http wiki ros org kinetic Installation Ubuntu 配置Ubuntu属性如下 xff1a https help ubuntu com community Repo
  • 关于ROS中的namespace

    当我们给发布的消息起名字时 xff0c 注意 34 points image 34 和 34 points image 34 是不一样的 xff0c 前者表示这个话题的名字是一个绝对名称 xff0c 它不在任何的namespace中 xff
  • 算法移植arm开发板小结(一)

    将windows的c c 43 43 代码移植到友善Tinny4412的arm上运行 首先要先将windows代码在ubuntu系统下编译通过 xff0c 然后在ubuntu系统下建立Tinny4412的arm交叉编译器 xff0c 并将代
  • CVTE嵌入式软件实习面经-已offer

    面试通过 时间线 4月份投的简历 xff0c 后面因为考试错过了 xff0c 后面月尾赶上最后了最后一场笔试 xff0c 笔试完四天左右通过 xff0c 通过两天后接到面试官电话 xff0c 那时候投了挺多公司的 xff0c 以为是其他的
  • 非对称加密详解

    非对称加密 1 非对称加密1 1 什么是非对称加密1 2 非对称加密通信流程1 3 RSA1 3 1 RSA加密1 3 2 RSA解密1 3 3 总结 1 4 ECC椭圆曲线 1 非对称加密 1 1 什么是非对称加密 非对称加密也叫公钥密码
  • PHP函数usort()解释

    定义和用法 usort 函数使用用户自定义的函数对数组排序 注释 xff1a 如果两个元素比较结果相同 xff0c 则它们在排序后的数组中的顺序未经定义 到 PHP 4 0 6 之前 xff0c 用户自定义函数将保留这些元素的原有顺序 但是
  • strchr()、strrchr()、strchrnul()…

    头文件 xff1a include 函数原型 xff1a char strchr char str int c char strrchr char str int c define GNU SOURCE 头文件 xff1a include
  • freertos- 任务调度器-vTaskStartScheduler()解析(笔记)

    1 全局状态量 系统时钟节拍计数器tick static volatile TickType t xTickCount 61 TickType t 0U 全局下一任务调度需要的阻塞时间 xff0c 用于及其唤醒任务static volati
  • freertos- 重要管理数据结构-列表List及其操作API (笔记)

    1 xff0c 源码中的位置 list h xff0c list c 2 xff0c 列表和列表项结构 列表项分为2种 xff1a struct xLIST ITEM listFIRST LIST ITEM INTEGRITY CHECK

随机推荐

  • 技术分享 | Javaer 如何做单元测试?

    前言 xff1a 本文适用于 javaer xff0c 其他开发者或许可以借鉴 写本文的主旨有两个 xff0c 一是简单的给大家介绍下单元测试 xff0c 二是通过一个简单的示例来介绍一些单元测试的技巧 xff0c 希望以此来降低大家写单元
  • 扩展卡尔曼滤波【转】

    1 重点看 SLAM中的EKF xff0c UKF xff0c PF原理简介 半闲居士 博客园 2 机器人重点看 定位 xff08 一 xff09 xff1a 扩展卡尔曼滤波 windSeS的博客 3 重点实例 扩展卡尔曼滤波 xff08
  • AGV - Background(1)- Company

    Company 米克力美 DZ 80无轨导航AGV小车采用windows10智能交互系统 xff0c xff08 米克力美工业AGV小车机器人采用安卓交互系统 xff09 可自动编程和程序化 xff0c 实现自主学习 使用人员无需培训即可轻
  • 无线路由器CPU浅析 MT7621A、 BCM47189 到底谁强?

    转自 xff1a http bbs 360 cn thread 14459037 1 1 html 在第一讲中 xff0c 已经粗略介绍过了目前路由芯片的四大厂 xff1a Broadcom xff08 博通 xff09 Qualcomm
  • STM32F4_串口通信详解

    目录 1 串口相关介绍及使用 1 1 串口设置的一般步骤 xff1a 1 1 1 串口时钟和GPIO时钟使能 1 1 2 设置引脚复用器映射 1 1 3 GPIO端口模式设置 1 1 4 串口参数初始化 1 1 5 开启中断并且初始化NVI
  • 嵌入式Linux设备驱动开发笔记(二)

    一 内核的时间 xff08 1 xff09 Tick xff08 滴答 xff09 内核采用了一个新的时间单位来进行计时 该时间单位称为tick 滴答 xff0c 一个tick对应硬件定时器两次中断之间的时间间隔 当前内核每秒钟硬件定时器会
  • Docker实现原理/容器原理(LXC,Cgroups,Docker)

    Docker实现原理 容器原理 Docker实现原理 容器原理什么是容器 Container 容器传统架构问题容器是什么容器如何实现 CgroupsCgroups是什么Cgroups解决什么问题Cgroups如何工作Cgroups层级结构
  • ros 编译 Python 文件

    参考自 xff1a http wiki ros org rospy tutorials Tutorials Makefile 系统 xff1a Ubuntu14 04 ros indigo py并不是可编译的脚本文件 xff0c 但是为了适
  • [Emuelec]在gamelist.xml中,为中文游戏名生成拼音字母

    1 通过python脚本将汉字拼音首字母查询出来 usr bin python3 coding UTF 8 filename transPinying py 功能 xff1a 获取传入中文的每个汉字的拼音首字母 pydic 61 34 吖a
  • 51单片机-宏晶STC程序调试、烧录、硬仿真

    内容包括STC单片机内部硬件介绍 xff08 寄存器 xff09 与程序的调试 硬仿真 xff0c STC15F硬仿真及其错误处理 xff0c MCS 51仿真介绍 xff0c 全自动下载介绍等 紫色文字是超链接 xff0c 点击自动跳转至
  • STM32单片机-汇编指令2

    目录 xff1a 11 STMFD和LDMFD指令 1 xff09 STMFD SP R0 R7 xff0c LR 2 xff09 LDMFD SP R0 R7 xff0c LR 99 伪指令 1 xff09 PROC伪指令 2 xff09
  • 多个switch case如何优化

    这段时间一直在整改代码圈复杂度 xff0c 我们的要求是每个函数方法圈复杂度不得大于5 xff0c 以下是整改的部分截图 希望对整改代码的你有所提示或帮助 xff0c 如果有更好的整改方法 xff0c 还望您不吝赐教哦 xff01
  • OPENCV检测矩形并计算其中心

    include 34 cv h 34 include 34 highgui h 34 include lt stdio h gt include lt math h gt include lt string h gt pragma comm
  • Jetson Xavier NX/AGX快速安装Intel Realsense SDK并使用D455

    Jetson Xavier NX AGX快速安装Intel Realsense SDK并使用D455 环境搭建及测试 1 安装脚本下载 xff1a github链接 xff1a https github com jetsonhacks in
  • AirSim无人机键盘控制

    AirSim仿真中实现多键盘按键控制 前言本文实现效果一 环境依赖二 多按键检测1 Pygame中的常用的键盘鼠标事件2 利用Pygame实现的多按键检测 AirSim中键盘控制实现下期预告 前言 有时候为了方便在AirSim调试无人机 x
  • 使用多电脑进行AirSim联合仿真

    文章目录 前言一 什么时候适合用两台电脑进行仿真 xff1f 二 怎么使用多电脑联合仿真 局域网内 1 获取UE4渲染端的IP地址2 修改程序接口 前言 随着仿真无人机数量的增加 xff0c 单台电脑越来越难以做到实时渲染 xff0c 这时
  • H.265编码原理入门

    视频编码的目的是为了压缩原始视频 xff0c 压缩的主要思路是从空间 时间 编码 视觉等几个主要角度去除冗余信息 由于 H 264 出色的数据压缩比率和视频质量 xff0c 成为当前市场上最为流行的编解码标准 而 H 265 是在 H 26
  • Go语言 GMP面试题(GMP调度示例)

    GMP面试题 第一段第二段 第一段 span class token keyword package span main span class token keyword import span span class token strin
  • 卡尔曼滤波里观测值凭什么用观测方程来表示?

    观测方程Z k 61 H X k 43 V k 为什么是由状态值和误差决定的 xff1f 不应该是由传感器输进去的吗 为啥只赋了一个初值 xff0c 就不再输入了 xff1f 在师兄解释下 xff0c 我终于明白了 因为这是仿真 xff01
  • Linux 内核的面向对象设计思想

    使用C语言实现面向对象设计的方法 Linux内核用C语言实现了面向对象的设计思想 即使用了三方面的特性 xff1a 封装 继承 多态 使用结构体实现了对对象的封装 xff1b 某一结构体成员中含有其他结构体的实例 xff0c 实现了一个结构