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