Skip to content

[Question] Understanding getting symbols from a dynamic library, unmapping, and RT_NODELETE #172

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

Closed
the-drunk-coder opened this issue Mar 26, 2025 · 1 comment
Labels

Comments

@the-drunk-coder
Copy link

the-drunk-coder commented Mar 26, 2025

Hi, I'm trying to load a plugin (VST3 plugin in my case) from a dynamic library, and I'm running into some issues that I'd like to understand better ...

The general procedure (pseudo-ish code) goes like this:

// PSEUDO-CODE ... 

let factory_ref: SmartPtrWrapper<PluginFactory> = unsafe {
    let lib = libloading::Library::new(lib_path.as_path()).expect("plugin not found");

    let func: libloading::Symbol<unsafe extern "C" fn() -> *mut PluginFactory> = lib
        .get(b"GetPluginFactory")
        .expect("plugin factory not found");

    // call plugin factory closure 
    let ptr = func();

    // on windows, I haven't found a workaround so far ... 
    #[cfg(target_os = "windows")]
    mem::forget(lib);

    SmartPtrWrapper::from_raw(ptr).unwrap()
};

On MacOS, that works just fine, but on both Linux and Windows, I get a segfault. On Linux, I have to load the library with RT_NODELETE, then it works. On Windows, it crashes with a segfault unless I call mem::forget.

I'm not sure what the implications are here, does that mean I'm intentionally leaking memory?

Or is the expectation that I keep a reference to the library as long as the pointer to GetPluginFactory AND its returned results are in use?

I've read in some other issue (can't find it anymore) that something might be unmapped when the Library instance is dropped, and I'm trying to understand better what that means ... any hints?

Best,
n

@nagisa
Copy link
Owner

nagisa commented Mar 26, 2025

Well yes, if you drop the Library the library that you've loaded gets unloaded, including whatever the resources that might be referenced by the ptr that GetPluginFactory returned. We use lifetimes for the most part to tie Library to Symbol (caveat #13,) but you're getting out of that by calling a function and storing a raw pointer that the function returned for you so at that point there aren't any lifetime guarantees that libloading could provide to you.

It probably works on macos because the library likely triggers one of the many exceptions that prevent library from being unloaded in the background (i.e. it behaves similarly to RT_NODELETE.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants