使用CXX实现Rust与C++之间的安全互操作性

CXX: 实现 Rust 与 C++ 互操作的安全桥梁

CXX 是一个允许 Rust 和 C++ 代码互调的工具,通过安全的低级绑定,避免了在 C 风格的不安全签名上构建外部函数接口的需求。CXX 的创建者 David Tolnay 在接受 InfoQ 采访时详细介绍了该工具的设计理念、实现挑战以及未来规划。

CXX 的核心功能与优势

  1. 类型和函数签名的静态分析:CXX 通过静态分析保护 Rust 和 C++ 的不变量,并使用代码生成器在两边高效实现边界,同时生成必要的静态断言以在构建过程中验证正确性。
  2. 零开销互操作:CXX 创建的桥梁几乎没有性能开销,不需要复制、序列化、内存分配或运行时检查。
  3. 原生代码风格:CXX 允许在桥梁的两侧编写完全符合各自语言习惯的代码,例如在 Rust 中使用符合 C++ 习惯的代码,反之亦然。CXX 提供了对标准库类型(如字符串、向量等)的内置绑定。

CXX 的使用示例

以下是一个使用 CXX 调用 C++ 代码的 Rust 程序示例:

#[cxx::bridge]
mod ffi {
    unsafe extern "C++" {
        include!("cxx-demo/include/blobstore.h");

        type BlobstoreClient;

        fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;
    }
}

fn main() {
    let client = ffi::new_blobstore_client();
}

David Tolnay 的背景与动机

David Tolnay 是一名专注于代码库设计的软件工程师,自 2016 年起开始使用 Rust,并创建和维护了许多广泛使用的 Rust 库。CXX 的诞生源于他对 Rust 与 C++ 互操作现状的不满。此前,Rust 与 C++ 的互操作需要通过 C 风格的接口,这不仅不安全,还增加了开发者的负担。CXX 的目标是通过更高的抽象层次实现 Rust 与 C++ 的无缝互操作,同时保持高效性。

CXX 的设计与实现挑战

CXX 最大的挑战之一是为 Cargo 用户提供良好的体验。Cargo 是 Rust 开源项目常用的构建系统,但其设计并不原生支持多语言构建。经过多次重新设计,CXX 在 Cargo 中的体验已经接近原生多语言构建系统的水平,支持 Rust 依赖 C++、C++ 依赖 Rust 以及 C++ 依赖其他 C++ 库的场景。

CXX 的现状与适用场景

Tolnay 表示,CXX 已经在大型混合 Rust-C++ 代码库中成功部署,得到了开发者的积极反馈。尽管仍有改进空间,但 CXX 提供的开发者体验已经足够成熟,适用于所有 Rust 与 C++ 互操作的场景。

CXX 的未来规划

CXX 的未来计划包括对异步函数的原生支持。目前,CXX 已经支持异步操作,但还不能直接在 Rust 中 .await 任意的 C++ 异步函数,或在 C++ 中 co_await 任意的 Rust 异步函数。

如何开始使用 CXX

开发者可以通过 CXX 教程GitHub 仓库 开始尝试使用 CXX。


CXX 通过安全的低级绑定和高效的代码生成,显著简化了 Rust 与 C++ 的互操作,为开发者提供了更流畅的开发体验。

阅读 56
0 条评论