我已经为 Rust 中的相机库编写了一个包装器,它命令和操作相机,还使用 bindgen 将图像保存到文件中。一旦我命令开始曝光(基本上是告诉相机拍摄图像),我可以使用以下形式的函数抓取图像:
pub fn GetQHYCCDSingleFrame(
handle: *mut qhyccd_handle,
w: *mut u32,
...,
imgdata: &mut [u8],) -> u32 //(u32 is a retval)
在 C++ 中,这个函数是:
uint32_t STDCALL GetQHYCCDSingleFrame(qhyccd_handle: *handle, ..., uint8_t *imgdata)
在 C++ 中,我可以传入表单的缓冲区,imgdata = new unsigned char[length_buffer]
该函数将使用来自相机的图像数据填充缓冲区。
在 Rust 中,类似地,我可以传入 Vec: 形式的缓冲区let mut buffer: Vec<u8> = Vec::with_capacity(length_buffer)
。
目前,我构建代码的方式是有一个主结构,其中包含图像的宽度和高度、相机句柄等设置,包括图像缓冲区。该结构已被初始化为mut
:
let mut main_settings = MainSettings {
width: 9600,
...,
buffer: Vec::with_capacity(length_buffer),
}
我编写了一个单独的函数,它将主结构作为参数并调用 GetQHYCCDSingleFrame 函数:
fn grab_image(main_settings: &mut MainSettings) {
let retval = unsafe { GetQHYCCDSingleFrame(main_settings.cam_handle, ..., &mut main_settings.image_buffer) };
}
调用此函数后,如果我立即检查 main_settings.image_buffer 的长度和容量:
println!("Elements in buffer are {}, capacity of buffer is {}.", main_settings.image_buffer.len(), main_settings.image_buffer.capacity());
我得到 0 作为长度,buffer_length 作为容量。类似地,打印任何索引,例如main_settings.image_buffer[0]
or 1 会导致恐慌退出说len is 0
.
这会让我认为GetQHYCCDSingleFrame
代码无法正常工作,但是,当我使用fitsio
and hdu.write_region
(fitsio docs linked here)将 image_buffer 保存到文件时,我使用:
let ranges = [&(x_start..(x_start + roi_width)), &(y_start..(y_start+roi_height))];
hdu.write_region(&mut fits_file, &ranges, &main_settings.image_buffer).expect("Could not write to fits file");
这会将实际图像保存到具有正确大小的文件中,并且是一个非常精细的图像(如果我使用 C++ 程序拍摄时的样子)。但是,当我尝试打印缓冲区时,由于某种原因是空的,但hdu.write_region
代码能够以某种方式访问数据。
目前,我的(不好的)解决方法是创建另一个向量,从保存的文件中读取数据并保存到缓冲区,然后该缓冲区具有正确数量的元素:
main_settings.new_buffer = hdu.read_region(&mut fits_file, &ranges).expect("Couldn't read fits file");
hdu.write_region
当函数可以从某个地方访问数据时,为什么我根本无法访问原始缓冲区,为什么它报告长度为 0 ?它究竟从哪里访问数据,我如何才能正确访问它?我对借用和引用有点陌生,所以我相信我在借用/引用缓冲区时可能做错了什么,还是别的什么?
对不起,长篇大论,但细节可能对这里的一切都很重要。谢谢!