I have this Rust function:
pub extern "C" fn do_something(my_string: &str) {
let s = String::from(my_string);
}
That I call on C++ with this:
std::string my_string("hello");
do_something(my_string.c_str());
Signature:
extern "C" void* do_something(const char*);
I get this error right on the String::from
line:
memory allocation of 127963177044160 bytes failedAborted (core dumped)
I guess that it's because the string passed has no \n
so it tries to make a string of the maximum size possible.
How to safely pass a std::string
to Rust?
That I call on C++ with this:
do_something(my_string.c_str());
So on the C++ side you're calling a function with a C string as input (not an std::string
, which is a very relevant distinction).
This means the Rust function should take a C string as input, which &str
definitely isn't.
Thus do_something
should be declared as:
pub extern "C" fn do_something(my_string: *const c_char) {
following which as Jmb notes you may want to use CStr
in order to safely wrap the pointer.
The &str
type is not FFI-safe. I would expect the Rust compiler to issue a warning to that effect. Rust slices consist of a pointer and a length and do not have a layout compatible with the C++ const char*
.
One option would be to have do_something
accept a pointer and a length (*const u8
and usize
, respectively), call std::slice::from_raw_parts
to exchange those for a &'a [u8]
, and call std::str::from_utf8_unchecked
to exchange that for a &str
. You must ensure the safety conditions documented along with each of those functions are upheld, including that the string contains valid UTF-8.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With