glutin/
lib_loading.rs

1//! Library loading routines.
2
3use std::ops::{Deref, DerefMut};
4use std::sync::Arc;
5
6use libloading::Library;
7
8#[cfg(windows)]
9use libloading::os::windows::{Library as WinLibrary, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS};
10
11pub 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)]
19pub struct SymWrapper<T> {
20    sym: T,
21    _lib: Arc<Library>,
22}
23
24impl<T: SymLoading> SymWrapper<T> {
25    pub unsafe fn new(lib_paths: &[&str]) -> Result<Self, ()> {
26        unsafe {
27            for path 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 = Library::new(path);
34
35                if let Ok(lib) = lib {
36                    return Ok(SymWrapper { sym: T::load_with(&lib), _lib: Arc::new(lib) });
37                }
38            }
39        }
40
41        Err(())
42    }
43}
44
45impl<T> Deref for SymWrapper<T> {
46    type Target = T;
47
48    fn deref(&self) -> &Self::Target {
49        &self.sym
50    }
51}
52
53impl<T> DerefMut for SymWrapper<T> {
54    fn deref_mut(&mut self) -> &mut Self::Target {
55        &mut self.sym
56    }
57}