abi_stable/library/
raw_library.rs

1use super::*;
2
3use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
4
5/// A handle to any dynamically loaded library,
6/// not necessarily ones that export abi_stable compatible modules.
7pub struct RawLibrary {
8    path: PathBuf,
9    library: LibLoadingLibrary,
10}
11
12impl RawLibrary {
13    /// Gets the full path a library would be loaded from,
14    pub fn path_in_directory(directory: &Path, base_name: &str, suffix: LibrarySuffix) -> PathBuf {
15        let formatted: String;
16
17        let is_64_bits =
18            cfg!(any(x86_64, powerpc64, aarch64)) || ::std::mem::size_of::<usize>() == 8;
19        let bits = if is_64_bits { "64" } else { "32" };
20
21        let maybe_suffixed_name = match suffix {
22            LibrarySuffix::Suffix => {
23                formatted = format!("{}-{}", base_name, bits);
24                &*formatted
25            }
26            LibrarySuffix::NoSuffix => base_name,
27        };
28
29        let name = format!("{}{}{}", DLL_PREFIX, maybe_suffixed_name, DLL_SUFFIX);
30        directory.join(name)
31    }
32
33    /// Loads the dynamic library at the `full_path` path.
34    pub fn load_at(full_path: &Path) -> Result<Self, LibraryError> {
35        // safety: not my problem if libraries have problematic static initializers
36        match unsafe { LibLoadingLibrary::new(full_path) } {
37            Ok(library) => Ok(Self {
38                path: full_path.to_owned(),
39                library,
40            }),
41            Err(err) => Err(LibraryError::OpenError {
42                path: full_path.to_owned(),
43                err: Box::new(err),
44            }),
45        }
46    }
47
48    /// Gets access to a static/function declared by the library.
49    ///
50    /// # Safety
51    ///
52    /// Passing a `T` of a type different than the compiled library declared is
53    /// undefined behavior.
54    ///
55    ///
56    ///
57    pub unsafe fn get<T>(&self, symbol_name: &[u8]) -> Result<LLSymbol<'_, T>, LibraryError> {
58        match unsafe { self.library.get::<T>(symbol_name) } {
59            Ok(symbol) => Ok(symbol),
60            Err(io) => {
61                let symbol = symbol_name.to_owned();
62                Err(LibraryError::GetSymbolError {
63                    library: self.path.clone(),
64                    symbol,
65                    err: Box::new(io),
66                })
67            }
68        }
69    }
70}