rust - 从函数返回 libusb::Device 的问题 - 尝试返回引用当前函数拥有的数据的值
问题描述
我想与 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
inDevice<'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
仍在范围内就可以使用。
推荐阅读
- ios - 无法将字符串隐式转换为 CBCharacteristic?
- google-sheets - 如果单元格值存在于不同的列中,则对范围内的单元格进行条件格式设置
- python - 如何让python不多次导入?
- c# - C# - 写入文本文件时,DB 字段中的双空格会导致不需要的换行符
- javascript - 如何将动态元素添加到从 React ref 中提取的特定 Html 节点?
- node.js - 如何使用 socket.io 创建房间?
- firebase - 尝试创建帐户时出现 Firebase 错误
- sql - 内连接产生笛卡尔积
- javascript - 创建一个随机数组来比较用户数组和西蒙说游戏上的闪烁
- python - 如何将我的函数应用于数据框的第一行?