我想与USB设备接口,所以我正在使用libusb。我有一个函数可以返回libusb::Device
我感兴趣的设备:
pub fn obtain_device() -> Device<'static> {
let context: Context = libusb::Context::new().unwrap();
let option: Device = context
.devices()
.unwrap()
.iter()
.find(|d| d.device_descriptor().unwrap().vendor_id() == 0x0bda)
.unwrap();
option
}
但是,这不能编译:
error[E0515]: cannot return value referencing local variable `context`
--> src/usb/mod.rs:19:5
|
18 | let option: Device = context.devices().unwrap().iter().find(|d| d.device_descriptor().unwrap().vendor_id() == 0x0bda).unwrap();
| ------- `context` is borrowed here
19 | option
| ^^^^^^ returns a value referencing data owned by the current function
以我的理解,context
即使不是我从函数返回的对象,也是导致问题的对象。看一下的定义libusb::Device
/// A reference to a USB device.
pub struct Device<'a> {
context: PhantomData<&'a Context>,
device: *mut libusb_device,
}
它包含对a的引用Context
,我认为这是编译失败的原因。但是我不确定如何Device
从函数中返回a ,或者我不正确地思考应该如何编码。如果我想将该Device
对象传递给其他函数怎么办?
根据定义Context::devices
,寿命'a
在Device<'a>
被绑定到的上下文的范围内,并且将成为无效(即会是一个悬空指针),如果Context
变为的范围进行。也就是说,板条箱不仅包装了指向将永远存在的设备的指针,而且还“通过”上下文访问了该设备。
解决此问题的一种方法是制作Context
静态内容,使其在程序的整个过程中都有效。您可以使用lazy_static
:
use lazy_static::lazy_static;
use libusb::{Context, Device};
lazy_static! {
static ref CONTEXT: Context = Context::new().unwrap();
}
pub fn obtain_device() -> Device<'static> {
CONTEXT
.devices()
.unwrap()
.iter()
.find(|d| d.device_descriptor().unwrap().vendor_id() == 0x0bda)
.unwrap()
}
您也可以将函数转换为拥有的结构的方法Context
。
pub struct MyDeviceContext {
context: libusb::Context,
}
impl MyDeviceContext {
pub fn new(context: libusb::Context) -> Self {
Self { context }
}
pub fn obtain_device(&self) -> Device<'_> {
self.context
.devices()
.unwrap()
.iter()
.find(|d| d.device_descriptor().unwrap().vendor_id() == 0x0bda)
.unwrap()
}
}
设备的寿命不再'static
,但是只要MyDeviceContext
仍在范围内就可以使用。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句