1 | //! Library loading routines. |
2 | |
3 | use std::ops::{Deref, DerefMut}; |
4 | use std::sync::Arc; |
5 | |
6 | use libloading::Library; |
7 | |
8 | #[cfg (windows)] |
9 | use libloading::os::windows::{Library as WinLibrary, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS}; |
10 | |
11 | pub trait SymLoading { |
12 | /// # Safety |
13 | /// The library must be unsured to live long enough. |
14 | unsafe fn load_with(lib: &Library) -> Self; |
15 | } |
16 | |
17 | #[derive (Clone)] |
18 | #[allow (missing_debug_implementations)] |
19 | pub struct SymWrapper<T> { |
20 | sym: T, |
21 | _lib: Arc<Library>, |
22 | } |
23 | |
24 | impl<T: SymLoading> SymWrapper<T> { |
25 | pub unsafe fn new(lib_paths: &[&str]) -> Result<Self, ()> { |
26 | unsafe { |
27 | for path: &&str in lib_paths { |
28 | #[cfg (windows)] |
29 | let lib = WinLibrary::load_with_flags(path, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS) |
30 | .map(From::from); |
31 | |
32 | #[cfg (not(windows))] |
33 | let lib: Result = Library::new(filename:path); |
34 | |
35 | if let Ok(lib: Library) = lib { |
36 | return Ok(SymWrapper { sym: T::load_with(&lib), _lib: Arc::new(data:lib) }); |
37 | } |
38 | } |
39 | } |
40 | |
41 | Err(()) |
42 | } |
43 | } |
44 | |
45 | impl<T> Deref for SymWrapper<T> { |
46 | type Target = T; |
47 | |
48 | fn deref(&self) -> &Self::Target { |
49 | &self.sym |
50 | } |
51 | } |
52 | |
53 | impl<T> DerefMut for SymWrapper<T> { |
54 | fn deref_mut(&mut self) -> &mut Self::Target { |
55 | &mut self.sym |
56 | } |
57 | } |
58 | |