nagisa / rust_libloading

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

Loading multiple independent instances the same library? #146

Closed alshdavid closed 5 months ago

alshdavid commented 5 months ago

I am trying to load the same library multiple times for the purposes of a plugin.

unsafe { libloading::Library::new(PathBuf.from("/path/to/lib.so")) }
unsafe { libloading::Library::new(PathBuf.from("/path/to/lib.so")) }

This seems to share state between the loaded libraries which is undesirable (the plugin uses global statics which causes conflicts when multiple instances are loaded).

I have tried to use:

let lib = unsafe {
  let lib = libloading::os::unix::Library::open(
    Some(PathBuf.from("/path/to/lib.so")),
    libloading::os::unix::RTLD_LOCAL
  ).unwrap();
  libloading::Library::from(lib)
};

However this give me the following error:

called `Result::unwrap()` on an `Err` value: 
  DlOpen { desc: "/path/to/lib.so: invalid mode for dlopen(): Invalid argument" }

Testing it out, if I copy the library multiple times (lib_copy1.so, lob_copy2.so, etc) - I can load that using Library::new() - I am just unsure how to get libloading to treat each instantiation as unique (I also need support for Windows).

nagisa commented 5 months ago

The only portable way to do this to the best of my knowledge is to have copies of the file with multiple names. If you're limited to GNU Linux, you may be able to achieve this with something like dlmopen that's been mentioned in this issue tracker in the past: https://github.com/nagisa/rust_libloading/issues/36. I wouldn't be surprised if Windows also had a system API to do something similar.

But either way you'll need to plumb all this manually. libloading is going to be fine with it so long as your underlying system-provided loader is.