Rust Vec to Ruby Array with FFI Segfaults
Rust Vec to Ruby Array with FFI Segfaults
我正在尝试 return 一个可以从外部 rust 函数转换为 Ruby 数组的结构,但是当我尝试调用结构 #to_a 方法时,我得到段错误。
use libc::size_t;
#[repr(C)]
pub struct Array {
len: libc::size_t,
data: *const libc::c_void,
}
impl Array {
fn from_vec<T>(mut vec: Vec<T>) -> Array {
vec.shrink_to_fit();
let array = Array { data: vec.as_ptr() as *const libc::c_void, len: vec.len() as libc::size_t };
mem::forget(vec);
array
}
}
#[no_mangle]
pub extern fn get_links(url: *const libc::c_char) -> Array {
// Get links
let mut urls: Vec<String> = vec![];
// push strings into urls vec
// urls => collections::vec::Vec<collections::string::String>
Array::from_vec(urls)
}
require 'ffi'
module Rust
extend FFI::Library
ffi_lib './bin/libembed.dylib'
class NodesArray < FFI::Struct
layout :len, :size_t, # dynamic array layout
:data, :pointer #
def to_a
self[:data].get_array_of_string(0, self[:len]).compact
end
end
attach_function :get_links, [:string], NodesArray.by_value
end
当我尝试在 ruby 中使用此函数时,它将 return Fii::NodesArray。我还可以从结构中获取 len 和数据。只有当我调用 #to_a 时才会出现段错误。
似乎 FFI::Pointer#get_array_of_string
有问题(或者它没有按照我的想法行事)。如果我更改此行,您的代码对我有用:
self[:data].get_array_of_string(0, self[:len]).compact
对此:
Array.new(self[:len]) {|i| self[:data].read_pointer[i * FFI::Pointer::SIZE].read_string }
Adrian 指出的问题是我将字符串推入 Vec。 FFI需要*const libc::c_char
,可以从String
.
转换过来
let mut urls: Vec<*const libc::c_char> = vec![];
urls.push(CString::new(string_var.value.to_string()).unwrap().into_raw());
我正在尝试 return 一个可以从外部 rust 函数转换为 Ruby 数组的结构,但是当我尝试调用结构 #to_a 方法时,我得到段错误。
use libc::size_t;
#[repr(C)]
pub struct Array {
len: libc::size_t,
data: *const libc::c_void,
}
impl Array {
fn from_vec<T>(mut vec: Vec<T>) -> Array {
vec.shrink_to_fit();
let array = Array { data: vec.as_ptr() as *const libc::c_void, len: vec.len() as libc::size_t };
mem::forget(vec);
array
}
}
#[no_mangle]
pub extern fn get_links(url: *const libc::c_char) -> Array {
// Get links
let mut urls: Vec<String> = vec![];
// push strings into urls vec
// urls => collections::vec::Vec<collections::string::String>
Array::from_vec(urls)
}
require 'ffi'
module Rust
extend FFI::Library
ffi_lib './bin/libembed.dylib'
class NodesArray < FFI::Struct
layout :len, :size_t, # dynamic array layout
:data, :pointer #
def to_a
self[:data].get_array_of_string(0, self[:len]).compact
end
end
attach_function :get_links, [:string], NodesArray.by_value
end
当我尝试在 ruby 中使用此函数时,它将 return Fii::NodesArray。我还可以从结构中获取 len 和数据。只有当我调用 #to_a 时才会出现段错误。
似乎 FFI::Pointer#get_array_of_string
有问题(或者它没有按照我的想法行事)。如果我更改此行,您的代码对我有用:
self[:data].get_array_of_string(0, self[:len]).compact
对此:
Array.new(self[:len]) {|i| self[:data].read_pointer[i * FFI::Pointer::SIZE].read_string }
Adrian 指出的问题是我将字符串推入 Vec。 FFI需要*const libc::c_char
,可以从String
.
let mut urls: Vec<*const libc::c_char> = vec![];
urls.push(CString::new(string_var.value.to_string()).unwrap().into_raw());