2015-07-02 21 views
3

我想返回一个结构,可以从一个外部的防锈功能转换成Ruby数组,但是当我尝试调用结构#to_a方法时,我得到一个段错误。Rust Vec到FFI的红宝石数组段segfaults

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 

当我尝试使用此功能在红宝石它会返回FII :: NodesArray。我也可以从结构中获取len和data。只有当我打电话给段故障的#to_a。

+0

我不熟悉Ruby FFI,但是......是'len'和'data'应该被颠倒吗?它在Rust中是'data','len',而在Ruby中是'len','data'。 –

+0

嗯。好点子。不过,我确实相信我在某一时刻拥有了正确的布局,并且仍然存在缺陷。我会尝试切换并更新问题。 – mpiccolo

+1

你现在有两个单独的定义,在你的锈源中有'Array'结构...请发布你使用的代码 – Adrian

回答

2

的问题,指出了Adrian,是我推弦成血管内皮细胞。 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()); 
1

似乎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 } 
+1

作为一个附注,你可能想考虑使用'std :: ffi :: CString' 'String' – Adrian

+0

太棒了。谢谢你阿德里安。 CString是我应该使用的。 – mpiccolo

+0

但有一个问题是我得到的只是指向数组中第一个sting的字符串数组。 所以我得到一个看起来像这样的数组: [“https://www.google.com/webhp?tab=ww”,“www.google.com/webhp?tab=ww”,“le .com/webhp?tab = ww“,”ebhp?tab = ww“,”= ww“,”\ t“,”“,”“,”“,”“,”“,”“,”“,”“ “,”“,”“,”“,”“,”“,”“,”“,”“,”“,”“,”“,”“,”“,” “”,“”,“”,“”] – mpiccolo