字符串通过FFI从生锈到红宝石变成空的

时间:2019-03-15 00:33:36

标签: ruby rust ffi

我有一个rubygem,其本机扩展名为rust。

本机扩展支持将其数据结构序列化为JSON。

但是,尽管我已经确认它会生成JSON,但在红宝石方面字符串始终为空。

这是红宝石代码:

module RustCuckooFilter
  extend FFI::Library
  ffi_lib 'libcuckoofilter_cabi'

  class Instance < FFI::AutoPointer
    def export(path)
      RustCuckooFilter.export(self)
    end
  end

  attach_function :export, :rcf_cuckoofilter_export, [Instance], :pointer

还有防锈码

/// Exports the filter to a file
#[no_mangle]
pub extern "C" fn rcf_cuckoofilter_export(filter: *mut rcf_cuckoofilter) -> *const c_char {
    let filter = unsafe { filter.as_mut() };
    let serialized = serde_json::to_string(&filter.expect("Given rcf_cuckoofilter* is a null pointer").export()).unwrap();
    let cstr = CString::new(serialized).expect("JSON was not a valid c string");
    let ptr = cstr.as_ptr();
    unsafe {
        println!("{:#?}", ptr);
        println!("{}", CStr::from_ptr(ptr).to_str().expect("validity"));
    }
    ptr
}

在Rust方面,println!使用确认指针包含JSON字符串。

通过将打印的地址与ruby中的#export的返回值进行比较,我可以看到使用了相同的指针。

但是,在指针上调用get_bytes(0, 10)会表明它以空字节开头,然后尝试将其转换为字符串会返回空字符串。

我怀疑它已经归零了,因为变量的生命周期已经结束,并且我正在调试模式下进行构建;但是,我不清楚我需要更改什么。

1 个答案:

答案 0 :(得分:2)

弄清楚了-我需要在锈侧使用CString::into_raw来防止清理。