使用Ruby FFI调用Rust lib时出现分段错误

时间:2015-05-25 13:57:41

标签: ruby rust ffi

我想将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")

2 个答案:

答案 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_charlibc::malloc处理手动管理内存。

This answer to "Rust FFI C string handling"提供了有关如何处理Rust中C字符串的更多详细信息。虽然问题的上下文是与C代码集成,但在您的情况下它应该同样有用。

答案 1 :(得分:0)

这是因为Ruby和Rust中“string”的定义不匹配。

Ruby FFI期望它是来自C的char*,即指向字符数组(see herecreate_object函数)的指针。因此Ruby尝试将其取消引用作为获取字符数据的指针并失败,因为它实际上并不是指针。

Rust有自己的String类,不仅仅是来自C的char*。以指针的形式从Rust导出字符串非常棘手且通用,足以deserve a separate question和{{3}应该帮助你。