I am currently trying to write a GUI application with gtk-rs, which uses one of my own libraries, I wrote a year ago.
Now I am hitting a problem with gtk-rs, where action callbacks can be connected via closures, but these require a
'static lifetime bound.
Here a link to an example, which is pretty much a stripped down version of the problem: Rust Playground
As you can see the I am trying to execute some action on my device, which is bound to the lifetime of the global API context via. a PhantomData in its struct definition.
Now the question: Can I work around this in my application, or do I have to change my previously written library, to use
refcounting instead of lifetimes?
I'm writing a gtk-rs application right now for viewing some specific weather data. I called it sonde. I have a large struct called AppContext that I put all the GUI and program state I might need to reference into. Then during program startup I put the AppContext in an Rc<RefCell<AppContext>> smart pointer. Then I have a GUI struct that I pass the smart pointer into during construction.
That's as clean as I've been able to get it with gtk-rs. It works really well once you get the hang of the patterns involved. It took me a while to figure all this out though, but I don't do much GUI programming.
But still I can not get the compiler to be happy. I just tried the approach with the context object,
but I can not put both my API and Device objects in there, because they reference each other.
Is there some solution to this problem (I heard of it, but always managed to work around it before by design).
I suspect you’re running into self-referential structs issue - your context object owns the API and Device but the API holds a reference to the Device, leading to a struct that has a reference to a part of itself (this isn’t allowed in Rust). There are some ways and libs to work around this, but lets confirm that is indeed your issue.
Take a look at the rental crate to see if it can help with the self-referencing aspect. Alternatively, is it possible to store just the Device in the context and access API from it when needed?
I do not know what you mean by just storing the device in the context. That`s exactly how I had done it before (I think?).
The problem is, that I am moving a device into the static closure (via a Rc), but the device still has a reference with a not static lifetime bound to the API outside the closure, so that wont work.
I also already tried to put both the API and device behind Rc`s, and move them both inside the closure, but because I instantiated the device before, the compiler can not really figure out, that the reference will stay valid (because the Rc owned by the closure will gurantee the API lifetime over the lifetime of the closure).
Can Device own the API instead of holding a reference? Maybe it can own an Rc of the API if you want to share ownership over it. Or you don’t have control over this? The bottom line is you won’t be able to move anything into a closure expecting 'static if it has any references.