I'm trying to make a shared library that can be loaded with libloading
. My hope was for this library to have an init()
function that would spawn a thread in the background, which other functions could send data to through channels, but I'm having a bit of an issue when unloading the library.
Just as a minimum reproducible example, I have two crates, test_lib
, compiled as a dylib and libloader
, just a binary.
In libloader/src/main.rs
:
use libloading::{Library, Symbol};
fn main() {
unsafe {
let lib = Library::new("test_lib").unwrap();
let init: Symbol<unsafe extern "C" fn()> = lib.get(b"init").unwrap();
init();
lib.close().unwrap();
}
}
In test_lib/src/lib.rs
:
#[no_mangle]
pub extern "C" fn init() {
std::thread::spawn(move || {
// Would not use in actual code,
// just need to keep the thread alive until drop.
loop {}
});
}
Everything works perfectly fine until lib.close()
, where the program crashes with the following error message:
error: process didn't exit successfully: `target\debug\libloader.exe` (exit code: 0xc0000005, STATUS_ACCESS_VIOLATION)
Is there any way to have background threads in a shared library?
Do I need to store the thread's JoinHandle
to join it in some sort of drop()
method?
Any help would be greatly appreciated.