我试图调用一个接受字符串的函数,用Rust编写。
然后将Rust代码编译为C并通过FFI gem包含在我的Ruby代码中。
当我调用Rust函数并传递一个字符串时,我什么都没得到。
Rust代码:
#[no_mangle]
pub extern fn speak(words: &str) {
println!("{}", words);
}
Ruby代码:
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!!")
答案 0 :(得分:4)
根据documentation,:string
表示以空字符结尾的字符串,在C中为char *
。&str
参数不等同于该类型:a { {1}}是一个复合值,由指针和长度组成。
最安全的解决方案是将Rust功能更改为接受&str
。然后,您可以使用CStr::from_ptr
和CStr::to_str
更轻松地使用它。
或者,您可以在Ruby代码中定义一个包含指针和长度的结构,并将其传递给Rust函数。但是,不能保证此结构总是与切片的内存布局匹配,因此为了100%安全,您应该在Rust代码中定义等效结构(使用*const c_char
),然后,使用此结构的字段,调用slice::from_raw_parts
来构建切片(#[repr(C)]
或&c_char
),然后您可以使用str::from_utf8
将其转换为&u8
。