I want to pass in a String
to a Rust lib, but it always throws a segmentation fault.
Here's the code:
// lib.rs
#[no_mangle]
pub extern fn process(foo: String) -> String {
foo
}
And the Ruby file:
# embed.rb
require 'ffi'
module Hello
extend FFI::Library
ffi_lib 'target/release/libembed.dylib'
attach_function :process, [ :string ], :string
end
puts Hello.process("foo")
Disclaimer: I've never used Ruby-FFI before; I'm going on what I can find in the documentation.
According to the Ruby-FFI wiki page on types, :string
is equivalent to a NUL-terminated C string. This is not the same as a Rust String
. A String
in Rust is (presently) three times larger!
The corresponding type in Rust would be *const ::libc::c_char
. Of note, there is also std::ffi::CString
, which is designed for creating C strings, and std::ffi::CStr
which is the safe wrapper type which can be created from either a CString
or a *const c_char
. Note that neither of these is compatible with *const c_char
!
In summary, to deal with C strings in Rust, you're going to have to juggle the types. Also keep in mind that, depending on what you're actually trying to do, you may need to also deal with manually managing memory using libc::malloc
and libc::free
.
This answer to "Rust FFI C string handling" gives more details on how to deal with C strings in Rust. Although the context for the question is integrating with C code, it should be equally useful in your case.
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