使用 Ruby FFI 调用 Rust 库时出现分段错误
Segmentation fault when calling a Rust lib with Ruby FFI
我想将 String
传递给 Rust 库,但它总是抛出分段错误。
代码如下:
// 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")
发生这种情况是因为 Ruby 和 Rust 中 "string" 的定义不匹配。
Ruby FFI 期望它是来自 C 的 char*
,即指向字符数组的指针(see here、create_object
函数)。所以 Ruby 试图将它解引用为指针以获取字符数据但失败了,因为它不是真正的指针。
Rust 有自己的 String
class,它不仅仅是来自 C 的 char*
。以指针形式从 Rust 导出字符串是棘手且通用的,足以 deserve a separate question, and this answer应该能帮到你。
免责声明:我以前从未使用过Ruby-FFI;我将继续我可以在文档中找到的内容。
根据 Ruby-FFI wiki page on types,:string
等同于以 NUL 结尾的 C 字符串。 这 与 Rust String
不同。 Rust 中的 String
(目前)大三倍!
Rust 中对应的类型是 *const ::libc::c_char
。值得注意的是,还有 std::ffi::CString
, which is designed for creating C strings, and std::ffi::CStr
是安全包装器类型,可以从 a CString
或 *const c_char
创建。请注意 这些都不兼容 *const c_char
!
总而言之,要在 Rust 中处理 C 字符串,您将不得不兼顾类型。另请记住,根据您实际尝试执行的操作,您可能还需要使用 libc::malloc
和 libc::free
.
手动管理内存
This answer to "Rust FFI C string handling" 提供了有关如何在 Rust 中处理 C 字符串的更多详细信息。尽管问题的上下文是与 C 代码集成,但它对您的情况应该同样有用。
我想将 String
传递给 Rust 库,但它总是抛出分段错误。
代码如下:
// 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")
发生这种情况是因为 Ruby 和 Rust 中 "string" 的定义不匹配。
Ruby FFI 期望它是来自 C 的 char*
,即指向字符数组的指针(see here、create_object
函数)。所以 Ruby 试图将它解引用为指针以获取字符数据但失败了,因为它不是真正的指针。
Rust 有自己的 String
class,它不仅仅是来自 C 的 char*
。以指针形式从 Rust 导出字符串是棘手且通用的,足以 deserve a separate question, and this answer应该能帮到你。
免责声明:我以前从未使用过Ruby-FFI;我将继续我可以在文档中找到的内容。
根据 Ruby-FFI wiki page on types,:string
等同于以 NUL 结尾的 C 字符串。 这 与 Rust String
不同。 Rust 中的 String
(目前)大三倍!
Rust 中对应的类型是 *const ::libc::c_char
。值得注意的是,还有 std::ffi::CString
, which is designed for creating C strings, and std::ffi::CStr
是安全包装器类型,可以从 a CString
或 *const c_char
创建。请注意 这些都不兼容 *const c_char
!
总而言之,要在 Rust 中处理 C 字符串,您将不得不兼顾类型。另请记住,根据您实际尝试执行的操作,您可能还需要使用 libc::malloc
和 libc::free
.
This answer to "Rust FFI C string handling" 提供了有关如何在 Rust 中处理 C 字符串的更多详细信息。尽管问题的上下文是与 C 代码集成,但它对您的情况应该同样有用。