Rust Vec for Ruby Array with FFI Segfaults
I'm trying to return a structure that can be converted to a Ruby array from an external rust function, but when I try to call the structs #to_a method, I get a segfault.
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
When I try to use this function in ruby ββit will return Fii :: NodesArray. I can also get len ββand data from a struct. Only when I call #to_a is it segfaults.
+3
source to share
2 answers
It seems to be FFI::Pointer#get_array_of_string
bugging (or it just doesn't do what I think it does). Your code works for me if I change this line:
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 }
+1
source to share