gpt4 book ai didi

rust - 在 C++ 类中包装 Rust 结构

转载 作者:行者123 更新时间:2023-11-29 07:49:32 30 4
gpt4 key购买 nike

我想在 C++ 类中包装一个 Rust 结构。

使用rust :

#[repr(C)]
pub struct RustStruct {
num: i32,
// other members..
}

pub extern "C" fn update(rust_struct: *mut RustStruct) {
(*rust_struct).num = 1i32;
}

extern "C" {
void update(void*);
}

C++:

class Wrapper {
public:
Wrapper();
// ..

private:
void* rustStruct;
// ..
};

Wrapper::Wrapper() {
update(rustStruct); // crash
}

int main() {
std::cout << "Testing..";
}

我明白为什么这行不通。我的问题是:我怎样才能实现我基本上想要做的事情(在 C++ 类中包装一个 Rust 结构)?

最佳答案

您的答案中混合了多个 FFI 概念,所以首先让我建议您阅读 Reference .

有两种方法可以达到你想要的效果,你可以:

  • 使用 POD struct(普通旧数据),又名 C 兼容结构
  • 使用不透明指针(C 中的void*)

像您那样将它们混合在一起是没有意义的。


Which to pick?

这两种解决方案各有优缺点,基本上是表现力与性能的权衡。

一方面,不透明指针更具表现力:它们可以指向任何 Rust 类型。然而:

  • 他们需要动态内存分配
  • 它们需要由 Rust 函数操作(因此总是间接地从 C 或 C++ 操作)

另一方面,POD 结构不需要其中任何一个,但它们仅限于可在 Rust 中表达的类型的子集。


How to use a POD?

实际上这是最简单的,所以让我们从它开始吧!

在 Rust 中:

#[repr(C)]
pub struct RustStruct {
num: i32,
// other members, also PODs!
}

在 C++ 中

struct RustStruct {
int32_t num;
// other members, also with Standard Layout
// http://en.cppreference.com/w/cpp/types/is_standard_layout
};

class Wrapper {
public:
private:
RustStruct rustStruct;
};

请注意,我只是同意你的问题 stricto censu 在这里,你实际上可以将两者合并到一个 C++ 类中:

class RustStruct {
public:
private:
int32_t num;
// other members, also with Standard Layout
// http://en.cppreference.com/w/cpp/types/is_standard_layout
};

只是避免方法。


How to use an opaque pointer?

这变得更棘手了:

  • 只有 Rust 代码可以正确地创建/复制/销毁类型
  • 谨防泄露...

因此,我们需要在 Rust 中实现很多功能:

#![feature(box_raw, box_syntax)]
use std::boxed;

pub struct RustStruct {
num: i32,
// other members, anything goes
}

pub extern "C" fn createRustStruct() -> *mut RustStruct {
boxed::into_raw(box RustStruct::new())
}

pub extern "C" fn destroyRustStruct(o: *mut RustStruct) {
boxed::from_raw(o);
}

好的...现在开始 C++:

struct RustStruct;

RustStruct* createRustStruct();
void destroyRustStruct(RustStruct*);

class Wrapper {
public:
Wrapper(): rustStruct(RustStructPtr(createRustStruct())) {}

private:
struct Deleter {
void operator()(RustStruct* rs) const {
destroyRustStruct(rs);
}
};

typedef std::unique_ptr<RustStruct, Deleter> RustStructPtr;

RustStructPtr rustStruct;
}; // class Wrapper

所以,是的,有点复杂,Wrapper 也不可复制(复制也必须委托(delegate)给 Rust)。无论如何,这应该可以帮助您入门!

注意:如果您有很多不透明的指针要包装,将复制/销毁函数作为模板参数的模板化 C++ 类可以减少大量样板代码。

关于rust - 在 C++ 类中包装 Rust 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32188582/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com