我有这个 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?
我用这个调用 C++:
Run Code Online (Sandbox Code Playgroud)do_something(my_string.c_str());
因此,在 C++ 方面,您使用C 字符串作为输入调用函数(不是std::string,这是一个非常相关的区别)。
这意味着 Rust 函数应该接受一个 C 字符串作为输入,这&str绝对不是。
因此do_something应声明为:
do_something(my_string.c_str());
Run Code Online (Sandbox Code Playgroud)
在 Jmb 注释之后,您可能希望使用CStr它来安全地包装指针。
该&str类型不是 FFI 安全的。我希望 Rust 编译器会发出警告。Rust 切片由一个指针和一个长度组成,并且没有与 C++ 兼容的布局const char*。
一种选择是do_something接受一个指针和一个长度(分别为*const u8和usize),调用std::slice::from_raw_parts将它们交换为 a &'a [u8],并调用std::str::from_utf8_unchecked将其交换为 a &str。您必须确保与这些功能一起记录的安全条件得到维护,包括字符串包含有效的 UTF-8。