-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Holding an InterfaceHandle in a struct #3
Comments
@awelkie Thanks for opening this issue. I wasn't aware that Rust's limitations would prevent storing a struct UsbDevice<'a> {
device:libusb::DeviceHandle<'a>,
interfaces: HashMap<u8,libusb::InterfaceHandle<'a>>,
}
impl<'a> UsbDevice<'a> {
fn interface(&mut self, iface: u8) -> ::libusb::UsbResult<&mut libusb::InterfaceHandle> {
// hand out references from `self.interfaces`
}
} but I run into lifetime issues every time I try to get something working, even when working with I think this (among other issues) needs to be overhauled for v0.2. A library shouldn't be this cumbersome to use. The only reason for each struct to hold references to the other structs was to have the Rust compiler enforce order of releasing resources ( |
Maybe the |
Actually, I think a simpler solution might be to use a 'PhantomData' objects in the structs instead of unused references to the parent struct. For example, the This way, objects have the right lifetimes but don't have references that keep them from being in the same struct. |
@awelkie I had never seen Since the libusb types are (internally) equivalent to |
@awelkie When I dug into it, I found that You can try it out now on the As an aside, I also replaced all of the references with |
Awesome, thanks for making these changes. I'm traveling now, so I won't be
|
So this fixed the issue with holding an 'InterfaceHandle' and a 'DeviceHandle' in the same struct. But I'm still running into the same issue with holding a 'Context' and 'DeviceHandle' in the same struct. What do you think about having the |
What's your use case for holding a |
The issue I was having was that I needed to initialize the context and device within a C callback. So I was hoping to bundle the context and device together and return it from the callback. But I solved the issue by using initializing the context in thread local storage. So I'm all good as far as this issue is concerned. Thanks for the changes! |
I'm having some trouble with this myself, I'm working on a library to deal with Steam Controller and I'd like to store the This is a problem because Does |
See #5, where I fixed that. |
This is due to a limitation where we can't hold a struct that has both the context and a device handle (that internally references back to it). The libusb context has to outlive the device handle. Github issue: dcuddeback/libusb-rs#3 Example solution via IRC: https://play.rust-lang.org/?gist=c68bda27266249c781e6335c4127f301&version=stable&mode=debug&edition=2015
I'm attempting something similar to what @meh is describing. I'd like to create a library that uses The only real workaround is as @dcuddeback mentioned and that's to create the Is there any better way to do this? |
What I did in my program was to move the Context into a Box and leak that box, giving me a |
@oberien Could you share some code snippet of how you did that? |
This is from a project I did some years ago: |
@oberien That was very helpful, thanks! A bit sad that that's how we are supposed to use this crate, there should really be an easier way. @dcuddeback, try build an example (in |
…to master * commit 'ab83741c9604a523a233c7722b1bae7c1bdb7511': [PKM-308] Using libusb_set_option() function instead of deprecated libusb_set_debug() function [PKM-308] Do not alter device reference count inside Device struct
https://github.com/a1ien/rusb does a pretty good job of solving this issue |
I'd like to have a struct that contains an
InterfaceHandle
objects so that I can use thebulk_transfer
method. I'm having trouble doing this because anInterfaceHandle
object contains a reference to aDeviceHandle
object, which contains a reference to aContext
object. I'd be fine having theContext
object be global, but I'd like to have theDeviceHandle
andInterfaceHandle
objects held in the same struct. But Rust has trouble with structs that contain references to objects within itself.So what's the best approach for having a struct contain an
InterfaceHandle
? I can see a few options:Rc
andRefCell
as is suggested by reem in this postDeviceHandle
, and then useclaim_interface
to get theInterfaceHandle
every time I need it.libusb-sys
crate directly, and just carry around the pointers.Here's an example of what I'm trying to do:
This fails to compile, saying that
dev_handle
does not live long enough.The text was updated successfully, but these errors were encountered: