Преобразование Ve c <& str> в Ve c <& CStr> в ржавчине - PullRequest
2 голосов
/ 05 января 2020

Посмотрите на эту функцию:

fn exec(cli: Vec<&str>) {
    eprintln!("execing: {:?}", cli);
    let args: Vec<&CStr> = cli.iter()
        .map(|s| CString::new(s.as_bytes()).unwrap().as_c_str())
        .collect();
    execv(args[0], &args);
    debug(args);
}

Она принимает Vec<&str> и выполняет ее как команду. У меня проблемы с преобразованием этого в Vec<&CStr> (что нужно execv). Компилятор сообщает об этой ошибке для операций map:

error[E0515]: cannot return value referencing temporary value
   --> src/idea.rs:141:18
    |
141 |         .map(|s| CString::new(s.as_bytes()).unwrap().as_c_str())
    |                  -----------------------------------^^^^^^^^^^^
    |                  |
    |                  returns a value referencing data owned by the current function
    |                  temporary value created here

Как я могу исправить эту ошибку?

1 Ответ

2 голосов
/ 06 января 2020

Вы должны собрать всю CString в отдельный вектор, чтобы ваши ссылки были действительны во время вызова execv:

use std::ffi::CString;
use std::ffi::CStr;

fn main() {
    let cli = vec!["hello", "world"];
    let vec: Vec<_> = cli.iter()
        .map(|s| CString::new(s.as_bytes()).unwrap())
        .collect();
    let vec_obj: Vec<&CStr> = vec.iter().map(|c| c.as_c_str()).collect();
    println!("CString:{:?}", vec);
    println!("&CStr:{:?}", vec_obj);
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c440ea898abe2ed5573993923ee6b74f

...