Exercise: Interoperability with C++

第一部分

  • 在您之前创建的 Rust 文件中,添加 #[cxx::bridge] 来指定一个将从 C++ 调用的函数(名为 hello_from_rust),该函数不接受任何参数也不返回任何值。
  • 修改之前的 hello_from_rust 函数,移除 extern "C"#[no_mangle]。现在,这只是一个标准的 Rust 函数。
  • 请修改 gn 目标以构建这些绑定。
  • 在 C++ 代码中,移除 hello_from_rust 的正向声明,然后添加生成的头文件。
  • Build and run!

第二部分

建议尝试操作一下 CXX。这有助于您更好地理解 Rust 在Chromium 中的灵活性。

Some things to try:

  • 从 Rust 回调到 C++。您需要执行以下操作:
    • 创建一个附加头文件,且您可以从 cxx::bridge 对其进行 include! 操作。您需要在这个新的头文件中声明要调用的 C++ 函数。
    • 创建一个 unsafe 代码块,用于调用此类函数,也可以在 #[cxx::bridge] 中指定 unsafe 关键字,如此处所述
    • 您可能还需要添加 #include "third_party/rust/cxx/v1/crate/include/cxx.h"
  • 将 C++ 字符串从 C++ 传递到 Rust。
  • 将对 C++ 对象的引用传递到 Rust。
  • 刻意让 Rust 函数签名与 #[cxx::bridge] 不匹配,并逐渐熟悉所看到的错误信息。
  • 刻意让 C++ 函数签名与 #[cxx::bridge] 不匹配,并适应您看到的错误。
  • 将某个类型的 std::unique_ptr 从 C++ 传递到 Rust,以便 Rust 拥有某个 C++ 对象的所有权。
  • 创建一个 Rust 对象并将其传递到 C++,以便 C++ 拥有它的所有权。(提示:您需要使用 Box)。
  • 声明调用某个 C++ 类型的方法。从 Rust 调用它们。
  • 声明调用某个 Rust 类型的方法。从 C++ 调用它们。

第三部分

现在,您已经了解了 CXX 互操作性的优势和局限,请思考几个 Rust 在 Chromium 中的应用场景,其中接口要足够简单构思该如何定义该接口。

如何获取帮助

As students explore Part Two, they’re bound to have lots of questions about how to achieve these things, and also how CXX works behind the scenes.

您可能会遇到以下问题:

  • 当我用类型 Y 初始化类型 X 的变量时,出现了初始化问题,其中 X 和 Y 都是函数类型。这是因为您的 C++ 函数实现与 cxx::bridge 中的声明并不完全一致。
  • 我好像能随意将 C++ 引用转换为 Rust 引用。这样不会导致 UB 风险吗?对于 CXX 的_不透明_类型,答案为否,因为它们的大小为零。对于 CXX 的基本类型,确实_有可能_导致 UB,但鉴于 CXX 的设计策略,要构建能导致这种情况的示例颇为困难。