繁体   English   中英

返回带有生命周期的FFI结构

[英]Return struct with lifetime for FFI

我正在尝试从woothee-rust板条箱向Ruby公开一个功能。 为此,我正在解析输入字符串,并尝试将结果作为C结构返回。 我遇到一个问题,即解析器的生存期“寿命不长”。 我不确定为什么解析器的生命周期必须超过该函数。

#![feature(libc)]
#![feature(cstr_to_str)]
#![feature(cstr_memory)]
extern crate libc;
extern crate woothee;

use woothee::parser::{Parser,WootheeResult};
use std::ffi::{CStr,CString};

#[no_mangle]
pub extern fn parse<'a>(ua_string: *const libc::c_char) -> WootheeResult<'a> {
    let input = unsafe { CStr::from_ptr(ua_string) };
    let parser = Parser::new();
    parser.parse(input.to_str().unwrap()).unwrap()
}

这是我得到的错误:

error: `parser` does not live long enough
  --> src/lib.rs:14:5
   |
14 |     parser.parse(input.to_str().unwrap()).unwrap()
   |     ^^^^^^ does not live long enough
15 | }
   | - borrowed value only lives until here
   |
note: borrowed value must be valid for the lifetime 'a as defined on the body at 11:77...
  --> src/lib.rs:11:78
   |
11 |   pub extern fn parse<'a>(ua_string: *const libc::c_char) -> WootheeResult<'a> {
   |  ______________________________________________________________________________^ starting here...
12 | |     let input = unsafe { CStr::from_ptr(ua_string) };
13 | |     let parser = Parser::new();
14 | |     parser.parse(input.to_str().unwrap()).unwrap()
15 | | }
   | |_^ ...ending here

扩展生存期选择后, Parser::parse的签名为

fn parse<'a, 'b>(&'a self, agent: &'b str) -> Option<WootheeResult<'a>>

换句话说:

给定对Parser的引用和对str的引用,可能返回WootheeResult ,其中包含一个或多个对Parser或其某些组件的引用。

但是,当函数退出时,您会立即销毁Parser 因此,不,您不能执行此操作,因为这样做将允许访问对未定义内存的引用。 Rust阻止您在程序中引入安全漏洞。

返回错误消息,希望现在更有意义:

  • parser寿命不足”
  • “借入的值必须在有效期内'a”有效

我没有深入研究woothee的实现,但是这个签名非常令人惊讶。 我可以理解它是否返回对已解析的字符串的引用,而不是对解析器的引用。 由于该方法需要&self这尤其令人惊讶-它不太可能基于解析来修改内部结构,所以为什么它返回对自身的引用?

看一下Parser::new的实现,生命周期似乎是由dataset::get_default_dataset驱动的:

pub fn get_default_dataset<'a>() -> HashMap<&'a str, WootheeResult<'a>>

如中所述, 有没有办法返回对在函数中创建的变量的引用? ,除非该局部变量为'static否则您不能返回对该局部变量的引用。 需要说明的是,我还没有尝试过,所以我80%可以确定可以将板条箱更改为从get_default_dataset返回'static字符串”,然后parse

impl<'a> Parser<'a> {
    fn parse<'b>(&'b self, agent: &'b str) -> Option<WootheeResult<'a>>
}

并且WootheeResult将是WootheeResult<'static> ,然后事情将“正常工作”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM