如何安全地将 C++ 字符串传递给 Rust?

Gue*_*OCs 4 c++ rust

我有这个 Rust 函数:

pub extern "C" fn do_something(my_string: &str) {
    let s = String::from(my_string);
}
Run Code Online (Sandbox Code Playgroud)

我用这个调用 C++:

std::string my_string("hello");
do_something(my_string.c_str());
Run Code Online (Sandbox Code Playgroud)

签名:

extern "C" void* do_something(const char*);
Run Code Online (Sandbox Code Playgroud)

我立即收到此错误String::from

memory allocation of 127963177044160 bytes failedAborted (core dumped)
Run Code Online (Sandbox Code Playgroud)

我猜这是因为传递的字符串没有,\n所以它试图制作一个最大大小的字符串。

如何安全地将 a 传递std::string给 Rust?

Mas*_*inn 8

我用这个调用 C++:

do_something(my_string.c_str());
Run Code Online (Sandbox Code Playgroud)

因此,在 C++ 方面,您使用C 字符串作为输入调用函数(不是std::string,这是一个非常相关的区别)。

这意味着 Rust 函数应该接受一个 C 字符串作为输入,这&str绝对不是。

因此do_something应声明为:

do_something(my_string.c_str());
Run Code Online (Sandbox Code Playgroud)

在 Jmb 注释之后,您可能希望使用CStr它来安全地包装指针。


mva*_*bem 6

&str类型不是 FFI 安全的。我希望 Rust 编译器会发出警告。Rust 切片由一个指针和一个长度组成,并且没有与 C++ 兼容的布局const char*

一种选择是do_something接受一个指针和一个长度(分别为*const u8usize),调用std::slice::from_raw_parts将它们交换为 a &'a [u8],并调用std::str::from_utf8_unchecked将其交换为 a &str。您必须确保与这些功能一起记录的安全条件得到维护,包括字符串包含有效的 UTF-8。

  • 或者使用专门针对此用例的 [`CStr`](https://doc.rust-lang.org/std/ffi/struct.CStr.html)。 (4认同)