【问题标题】:How do I call a C++ constructor using the cxx crate?如何使用 cxx crate 调用 C++ 构造函数?
【发布时间】:2020-08-29 22:25:03
【问题描述】:

我找到了this question,但它已经有 3 年历史了,从那时起,像 cxx 这样的板条箱已经出现。现在是否可以从 Rust 构造一个 C++ 对象,还是我仍然需要创建一个 shim?

【问题讨论】:

标签: c++ rust ffi


【解决方案1】:

就构造函数按值“返回”一个 C++ 类型而言,它们不能转换为 Rust,因为 Rust 移动 (memcpy) 与 C++ 移动不兼容(这可能需要调用移动构造函数)。将任意构造函数转换为 fn new() -> Self 是不正确的。

您可以使用 assumes moving without a constructor call is okay 的 bindgen 不安全地绑定它们,或者您可以使用自述文件中的“共享结构”方法,该方法可以在任何一种语言中安全移动,或者您可以 include! 一个 shim,它在unique_ptr 或类似的。

最后一种方法看起来像:

// suppose we have a struct with constructor `ZeusClient(std::string)`

// in a C++ header:
std::unique_ptr<ZeusClient> zeus_client_new(rust::Str arg);

// in the corresponding C++ source file:
std::unique_ptr<ZeusClient> zeus_client_new(rust::Str arg) {
  return make_unique<ZeusClient>(std::string(arg));
}

// in the Rust cxx bridge:
extern "C++" {
    include!("path/to/zeus/client.h");
    include!("path/to/constructorshim.h");

    type ZeusClient;

    fn zeus_client_new(arg: &str) -> UniquePtr<ZeusClient>;
}

在未来,CXX 很可能会为这种模式包含一些内置的东西,或者可能是针对没有移动构造函数的结构的特殊情况。这是在dtolnay/cxx#280 中跟踪的。

extern "C++" {
    type ZeusClient;

    fn new(arg: &str) -> ZeusClient;  // will verify there is no move constructor

    fn new(arg: &str) -> UniquePtr<ZeusClient>;  // okay even with move constructor
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    • 1970-01-01
    • 2011-12-12
    • 2016-02-29
    相关资源
    最近更新 更多