【发布时间】:2015-01-23 21:31:05
【问题描述】:
我正在尝试编写一个函数,将命令行实用程序 (image-magick) 的标准输出加载到结构的成员中。我想既然图片可能是MB,我还是尽量避免复制吧。
/// An image data container used internally.
/// Images are 8-bit single channel for now.
pub struct Image<'a> {
/// Width of the image in pixels.
pub width: u32,
/// Height of the image in pixels.
pub height: u32,
/// The buffer containing the image data, as a slice.
pub pixels: &'a [u8],
}
// Load a file by first using imageMagick to convert it to a .pgm file.
fn load_using_magick<'a>(path: Path) -> Image<'a> {
use std::io::Command;
let output:IoResult<ProcessOutput> = Command::new("convert")
.arg("-format pgm")
.arg("-depth 8")
.arg(path)
.arg("-")
.output();
let output_unwrapped:ProcessOutput = match output {
Ok(o) => o,
Err(e) => panic!("Unable to run ImageMagick's convert tool in a separate process! convert returned: {}", e),
};
let bytes: &[u8] = match output_unwrapped.status.success() {
false => panic!("signal or wrong error code from sub-process?"),
true => output_unwrapped.output.as_slice(),
};
// Note, width and height will eventually get parsed out of "bytes"
// and the returned Imaeg.pixels will point to a slice of the (already)
// heap allocated memory. I just need to figure out ownership first...
Image{width:10,height:10,pixels:bytes}
}
当调用标准库 std::io::Process::Command::output() 时,我想保留的大块堆是由标准库(或者可能是内核?)分配的。
借用检查器编译失败:
src/loaders.rs:41:17: 41:40 error: `output_unwrapped.output` does not live long enough
src/loaders.rs:41 true => output_unwrapped.output.as_slice(),
^~~~~~~~~~~~~~~~~~~~~~~
src/loaders.rs:21:51: 48:2 note: reference must be valid for the lifetime 'a as defined on the block at 21:50...
src/loaders.rs:21 fn load_using_magick<'a>(path: Path) -> Image<'a> {
src/loaders.rs:22 use std::io::Command;
src/loaders.rs:23
src/loaders.rs:24 let output:IoResult<ProcessOutput> = Command::new("convert")
src/loaders.rs:25 .arg("-format pgm")
src/loaders.rs:26 .arg("-depth 8")
...
src/loaders.rs:21:51: 48:2 note: ...but borrowed value is only valid for the block at 21:50
src/loaders.rs:21 fn load_using_magick<'a>(path: Path) -> Image<'a> {
src/loaders.rs:22 use std::io::Command;
src/loaders.rs:23
src/loaders.rs:24 let output:IoResult<ProcessOutput> = Command::new("convert")
src/loaders.rs:25 .arg("-format pgm")
src/loaders.rs:26 .arg("-depth 8")
这对我来说有点道理;拥有我试图保留的数据块的任何东西都超出了范围,在我按值返回的结构中留下了一个悬空指针。那么我如何在返回之前将内存区域的所有权实际转移到我的结构中呢?
我已经阅读了Rust Lifetimes Manual。
【问题讨论】:
-
我的代码在这里,如果它更容易检查的话:github.com/drewm1980/rust-omr/commit/… (run "cargo test")
-
您不应该使用盒装值吗? (我可能已经过时或完全错误)
-
@logan,delnan 建议在下面将 Vec
粘贴到我的结构中。我〜认为这算作盒装类型。我也只是尝试将 Vec 粘贴到 Box 中并将 ~that 粘贴到我的结构中。这些都不允许我在结构中保留一个指向我关心的子数组的切片。
标签: memory-management struct rust object-lifetime