除非您计划完全重写内核并部署一个完整的新标准化导出名称(这意味着丢弃所有现有的可执行文件),我认为这几乎是不可能的。许多 C++ 特性实际上是元函数,编译器必须将其转换为存在的东西。
像std::thread 这样的东西可以被实现为内核资源的包装器(这很可能是一个“指向数据结构的指针:这就是 HANDLE 的真正含义),通过让这些结构驻留在另一个处理并对 client 程序完全不透明。
像函数调用这样的东西来保持这种不透明度需要一个所有语言都可以依赖的标准ABI(应用程序二进制接口),同时生成必须链接的目标代码.
现在,C ABI - 由于缺少重载 - 是微不足道的(只需将 _ 附加到函数名称:这是 Windows 内核库采用的约定,每个编译器开发人员在制作它的 windows 版本),但 C++ 名称修饰是......专有的(没有关于它必须如何在系统级别完成的定义,所以每个编译器都有自己的)。
因此,唯一可靠的内核将是仅导出extern "C" 的内核。
它可以在内部用 C++ 编写,但它的接口在任何情况下都必须是纯 C(这只是你的 class* function();,它在语义上与 HANDLE CreateClass() 没有区别。
请注意,即使在 C++ 规范级别定义标准 ABI 也无济于事:所有 C++ 编译器都将链接相同,但不需要遵循其他语言。
而且系统级 ABI 必须足够简单,才能不需要并非所有语言都必须支持的客户端语言特性(如函数重载)。
更复杂的是,C++ 也有模板,在编译期间实例化代码,并且无法跨进程边界或内核屏障可靠地实现:想象内核内部有 vector<int> 和 vector<double>:我可以依赖在系统上我必须使用这些功能,但是vecotr<foo> 呢?
在我的机器上编译我的软件期间,我如何要求我所有用户的系统内核使vector<foo> 存在?这可以在安装过程中完成,但同样需要对通信接口进行更多标准化。
内核是存在于汇编器级别的物理资源的管理器。用 C 表示它们几乎是微不足道的。如果您使用 C++ 低级功能(与 C 基本相同),用 C++ 表示它们仍然是微不足道的,但是 - 一旦您升入抽象 - 您会立即遇到标准化缺失和关于位置的复杂非平凡选择以及如何实现这一点将转化为未来对内核级别的使用可能没有如此明确定义的事物的约束。
当然,原则上没有什么禁止在内核实现内部使用 C++,但这会在跨资源使用的边界管理中产生问题。
实际的协议是“让我访问资源”和“保留您的资源”。
客户端程序可以将这两个调用包装在一个 RAII 类中,并在其上应用所有 C++11 功能,但是将其移到边界的另一侧呢?
内核可以返回win::unique<something> 吗?嗯......不是真的,因为你不能破坏你自己进程中没有的东西:那个“samrt句柄”将有一个析构函数,导致另一个内核函数调用。 o 内核在任何情况下都会有一个单独的创建/获取和删除/释放函数。
我当然可以根据智能句柄为您的 C++ 程序开发一个 API,但程序与内核的通信仍将通过普通函数(因此智能句柄都管理到客户端,无论如何)
类似地,如果调用都是同步的,则堆栈展开有效,但创建/删除本身不是同步的(它们不是在另一个内部调用)。它们通过 RAII 模式通过驻留在您的堆栈中的本地对象“同步”。但是*HPEN(注意取消引用)结构不在您的堆栈中:位于另一个进程(GDI 驱动程序)中,因此smart<HPEN> 必须在构造时调用CreatePen,在销毁时调用DeletePen,因为内核 -本身 - 无法知道您的“展开”(即您的,而不是内核)何时会到达正确的点。
C++ //in kernel// 可以存在于完全由内核本身在同一个内核调用中同步构造和销毁的对象,然后 - 结果 - 不会离开内核,以某种方式被内核使用客户。这当然是可能的,但是由于内核的目的是导出功能并且导出需要平面 API,因此您很快将使用 C++ 内核导出客户端 C++ 包装器使用的普通 C 接口。
我怀疑这种努力是否合理。