温馨提示×

怎么用Linux C++写驱动

小樊
38
2026-08-27 09:22:13
栏目: 编程语言

Linux 上用 C++ 写驱动这件事,需要先澄清一个重要事实

Linux 内核驱动只能用 C 写(不能用标准 C++)
不能用 STL、new/delete、异常、RTTI、libstdc++

不过,可以用“受限的 C++ 语法” 来写内核代码,比如:

  • 类(class)
  • 内联函数
  • 简单继承
  • 构造函数(不能抛异常)

下面我分 原理 → 示例 → 能不能用 C++ → 替代方案 给你讲清楚。


一、Linux 驱动的基本事实

1️⃣ Linux 驱动运行在哪里?

  • 运行在 内核空间(kernel space)
  • 不是普通用户程序
  • 没有 libc、没有 libstdc++

2️⃣ 内核编译环境

  • 使用 Linux 内核源码的构建系统(Kbuild)
  • 编译器是 gcc,不是 g++
  • 不支持:
    • iostream
    • vector
    • new / delete
    • 异常(try/catch

二、标准做法:用 C 写驱动(推荐)

1️⃣ 最简单的字符设备驱动示例(C)

hello.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>

#define DEVICE_NAME "hello"

static int major;

static int hello_open(struct inode *inode, struct file *file) {
    printk(KERN_INFO "hello open\n");
    return 0;
}

static struct file_operations fops = {
    .open = hello_open,
};

static int __init hello_init(void) {
    major = register_chrdev(0, DEVICE_NAME, &fops);
    printk(KERN_INFO "hello module loaded, major=%d\n", major);
    return 0;
}

static void __exit hello_exit(void) {
    unregister_chrdev(major, DEVICE_NAME);
    printk(KERN_INFO "hello module unloaded\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("example");

Makefile

obj-m += hello.o

all:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

编译 & 加载:

make
sudo insmod hello.ko
dmesg | tail
sudo rmmod hello

三、能不能用 C++ 写 Linux 驱动?

✅ 技术上:可以(但非常受限)

❌ 工程上:强烈不推荐

原因

项目 是否支持
class
构造函数 ✅(不能抛异常)
继承 ✅(简单)
STL
new/delete
异常
libstdc++

内核里 没有 C++ 运行时,所以:

std::cout << "hello";  // ❌ 不可能

四、用“受限 C++”写驱动的示例(不推荐)

hello.cpp

extern "C" {
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
}

class HelloDevice {
public:
    HelloDevice() {
        printk(KERN_INFO "HelloDevice constructed\n");
    }
};

static HelloDevice dev;

extern "C" int init_module(void) {
    printk(KERN_INFO "C++ driver loaded\n");
    return 0;
}

extern "C" void cleanup_module(void) {
    printk(KERN_INFO "C++ driver unloaded\n");
}

MODULE_LICENSE("GPL");

⚠️ 注意:

  • 所有导出符号必须是 extern "C"
  • 不能调用任何 C++ 标准库

五、推荐的正确架构(重要)

✅ 实际工程中的做法

┌────────────┐
│ 用户程序   │  C / C++ / Qt / Python
└─────┬──────┘
      │ ioctl / read / write
┌─────▼──────┐
│ 内核驱动   │  C(标准做法)
└─────┬──────┘
      │
┌─────▼──────┐
│ 硬件       │
└────────────┘

逻辑用 C++ 写驱动用 C 写通过 ioctl / netlink / mmap 交互


六、如果你“想用 C++ 写驱动”,我建议你这样做

✅ 正确选择

需求 推荐方案
学习驱动 C
复杂逻辑 用户态 C++
高性能 C 驱动 + C++ 用户程序
工业项目 C 驱动

七、学习路线建议

  1. ✅ 先学 Linux 驱动基础(C)
  2. ✅ 字符设备驱动
  3. ✅ platform / device tree
  4. ✅ ioctl / mmap
  5. ✅ 再看内核源码

八、我可以继续帮你

你可以直接告诉我:

  • ✅ 是 字符设备 / 块设备 / 网络设备
  • ✅ 是 ARM / x86 / 树莓派 / 嵌入式
  • ✅ 是 学习 / 项目 / 面试
  • ✅ 想写 什么硬件驱动

我可以直接给你 可编译的完整驱动模板

0