我想将String
传递给Rust lib,但它总是会引发分段错误。
以下是代码:
// lib.rs
#[no_mangle]
pub extern fn process(foo: String) -> String {
foo
}
Ruby文件:
# 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")
答案 0 :(得分:6)
免责声明:我之前从未使用过Ruby-FFI;我正在进行文档中的搜索。
根据Ruby-FFI wiki page on types,:string
相当于NUL终止的C字符串。 与Rust String
相同。 Rust中的String
(目前)大三倍!
Rust中的相应类型为*const ::libc::c_char
。值得注意的是,还有std::ffi::CString
,用于创建C字符串,std::ffi::CStr
是安全的包装类型,可以从创建 a {{1}或CString
。请注意,这两者都不兼容*const c_char
!
总之,要处理Rust中的C字符串,您将不得不处理这些类型。另请注意,根据您实际尝试的操作,您可能还需要使用*const c_char
和libc::malloc
处理手动管理内存。
This answer to "Rust FFI C string handling"提供了有关如何处理Rust中C字符串的更多详细信息。虽然问题的上下文是与C代码集成,但在您的情况下它应该同样有用。
答案 1 :(得分:0)
这是因为Ruby和Rust中“string”的定义不匹配。
Ruby FFI期望它是来自C的char*
,即指向字符数组(see here,create_object
函数)的指针。因此Ruby尝试将其取消引用作为获取字符数据的指针并失败,因为它实际上并不是指针。
Rust有自己的String
类,不仅仅是来自C的char*
。以指针的形式从Rust导出字符串非常棘手且通用,足以deserve a separate question和{{3}应该帮助你。