【问题标题】:String becomes empty passing through FFI from rust to ruby字符串通过 FFI 从 rust 变为 ruby​​ 变为空
【发布时间】:2019-03-15 00:33:36
【问题描述】:

我有一个 ruby​​gem,其原生扩展是用 rust 编写的。

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

然而,虽然我已经确认它正在生成 JSON,但字符串在 ruby​​ 端始终为空。

这是红宝石代码:

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) 表明它以空字节开头,并且尝试将其转换为字符串会返回一个空字符串。

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

【问题讨论】:

标签: ruby rust ffi


【解决方案1】:

想通了 - 我需要在生锈的一面使用 CString::into_raw 以防止它被清理。

【讨论】:

  • 如果你给了所有权,别忘了释放内存你必须在某个时候使用from_raw()
猜你喜欢
  • 2014-07-31
  • 2012-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-18
  • 1970-01-01
  • 2017-08-08
  • 2013-09-18
相关资源
最近更新 更多