1

I'm trying to call a function which accepts a string, written in Rust.

The Rust code is then compiled to C and included in my Ruby code via the FFI gem.

When I call the Rust function and pass a string I get nothing.

Rust code:

#[no_mangle]
pub extern fn speak(words: &str) {
  println!("{}", words);
}

Ruby code:

require 'ffi'

module Human
  extend FFI::Library
  ffi_lib '../target/release/libruby_and.dylib'
  attach_function :speak, [:string], :void
end

Human.speak("Hello, we are passing in an argument to our C function!!")
1

1 Answer 1

4

According to the documentation, :string represents a null-terminated string, which is char * in C. The &str argument is not equivalent to that type: a &str is a compound value, composed of a pointer and a length.

The safest solution is to change your Rust function to accept a *const c_char instead. You can then use CStr::from_ptr and CStr::to_str to work with it more easily.

Alternatively, you could define a struct in your Ruby code that contains a pointer and a length, and pass that to the Rust function. However, there's no guarantee that this struct will always match the memory layout of a slice, so to be 100% safe, you should define the equivalent struct in your Rust code (with #[repr(C)]), then, using the fields of this struct, call slice::from_raw_parts to construct a slice (&c_char or &u8), which you can then turn into a &str with str::from_utf8.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.