nagisa / rust_libloading

Bindings around the platform's dynamic library loading primitives with greatly improved memory safety.
https://docs.rs/libloading
ISC License
1.24k stars 102 forks source link

Trying to store loaded function #155

Closed zxcqirara closed 2 months ago

zxcqirara commented 2 months ago

I want to store function somewhere to invoke it later in the code but every time I try to do it, rust throws STATUS_ACCESS_VIOLATION error. If I store Symbol<fn()> then it says that Library "does not live long enough"

nagisa commented 2 months ago

Well, the last sentence does explain it all, doesn't it? Library needs to live for as long as you want to use your Symbols. If not crash, what other well defined things could possibly happen when working with functions from an unloaded library?

There are plenty of different approaches to ensure that Library lives for long enough: one of them being to leak the Library, either by using appropriate flags at the time Library is loaded or by mem::forgeting the Library once you've obtained your function pointers out of it. At that point you can store the function pointer wherever as if it the underlying code had a 'static lifetime.

The ecosystem also has some options that combine a Library and its symbols into a single struct, so you don't need to worry about lifetimes, while still ensuring proper clean-up. For instance, the bindgen crate can generate something for you here (or you could draw inspiration from it's implementation...)

nagisa commented 2 months ago

For what it is worth, some of the issues you've encountered are related to https://github.com/nagisa/rust_libloading/issues/46, which is unfortunately still isn't easily solvable in the present-day Rust (due to fn() function pointers implying the 'static lifetime.)

zxcqirara commented 2 months ago

There are plenty of different approaches to ensure that Library lives for long enough: one of them being to leak the Library, either by using appropriate flags at the time Library is loaded or by mem::forgeting the Library once you've obtained your function pointers out of it. At that point you can store the function pointer wherever as if it the underlying code had a 'static lifetime.

Can you please explain your thought about flags? I didn't really work with such things before, so sorry about this question

nagisa commented 2 months ago

Some of the targets support options to loading functions like Linux's RTLD_NODELETE which will prevent the library from being unloaded when a function to unload the dynamic library is invoked. libloading::os APIs provide an ability to pass such flags through. Not sure if there's such a flag for Windows, though, so mem::forget is a more sure-fire method here.

zxcqirara commented 2 months ago

I have already realized it via the mem::forget, but thank you anyway!

zxcqirara commented 2 months ago

ig I can close the issue