1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//! Provides shared library access for Unix like systems.
use crate::{core::optional::NSTDOptional, NSTDAny, NSTDAnyMut, NSTDChar};

/// Represents an owned handle to a dynamically loaded library.
#[repr(C)]
pub struct NSTDUnixSharedLib {
    /// A raw handle to the shared library.
    handle: NSTDAnyMut,
}
impl Drop for NSTDUnixSharedLib {
    /// [NSTDUnixSharedLib]'s destructor.
    #[inline]
    fn drop(&mut self) {
        // SAFETY: `self` is valid.
        unsafe { nstd_os_unix_shared_lib_free(core::ptr::read(self)) };
    }
}
// SAFETY: `NSTDUnixSharedLib` owns a handle to the dynamically loaded library.
unsafe impl Send for NSTDUnixSharedLib {}
// SAFETY: `NSTDUnixSharedLib` does not undergo interior mutability.
unsafe impl Sync for NSTDUnixSharedLib {}

/// Represents an optional `NSTDUnixSharedLib`.
pub type NSTDUnixOptionalSharedLib = NSTDOptional<NSTDUnixSharedLib>;

extern "C" {
    /// Loads a dynamically loaded shared library.
    ///
    /// # Parameters:
    ///
    /// - `const NSTDChar *path` - A path to the shared library to load.
    ///
    /// # Returns
    ///
    /// `NSTDUnixOptionalSharedLib lib` - A handle to the loaded library.
    ///
    /// # Safety
    ///
    /// See <https://man7.org/linux/man-pages/man3/dlopen.3.html>.
    pub fn nstd_os_unix_shared_lib_load(path: *const NSTDChar) -> NSTDUnixOptionalSharedLib;

    /// Returns a raw handle to a dynamically loaded library.
    ///
    /// # Parameters:
    ///
    /// - `const NSTDUnixSharedLib *lib` - The shared library.
    ///
    /// # Returns
    ///
    /// `NSTDAnyMut handle` - A raw handle to the dynamically loaded library.
    pub fn nstd_os_unix_shared_lib_handle(lib: &NSTDUnixSharedLib) -> NSTDAnyMut;

    /// Returns an immutable opaque pointer to a symbol in a loaded library.
    ///
    /// # Parameters:
    ///
    /// - `const NSTDUnixSharedLib *lib` - The shared library.
    ///
    /// - `const NSTDChar *symbol` - The symbol to retrieve a pointer to.
    ///
    /// # Returns
    ///
    /// `NSTDAny ptr` - A pointer to the loaded symbol, null on error.
    ///
    /// # Safety
    ///
    /// See <https://man7.org/linux/man-pages/man3/dlsym.3.html>.
    pub fn nstd_os_unix_shared_lib_get(lib: &NSTDUnixSharedLib, symbol: *const NSTDChar)
        -> NSTDAny;

    /// Returns a mutable opaque pointer to a symbol in a loaded library.
    ///
    /// # Parameters:
    ///
    /// - `NSTDUnixSharedLib *lib` - The shared library.
    ///
    /// - `const NSTDChar *symbol` - The symbol to retrieve a pointer to.
    ///
    /// # Returns
    ///
    /// `NSTDAnyMut ptr` - A pointer to the loaded symbol, null on error.
    ///
    /// # Safety
    ///
    /// See <https://man7.org/linux/man-pages/man3/dlsym.3.html>.
    pub fn nstd_os_unix_shared_lib_get_mut(
        lib: &mut NSTDUnixSharedLib,
        symbol: *const NSTDChar,
    ) -> NSTDAnyMut;

    /// Closes and frees a loaded shared library.
    ///
    /// # Parameters:
    ///
    /// - `NSTDUnixSharedLib lib` - A handle to the loaded library to unload.
    ///
    /// # Safety
    ///
    /// See <https://man7.org/linux/man-pages/man3/dlclose.3p.html>.
    pub fn nstd_os_unix_shared_lib_free(lib: NSTDUnixSharedLib);
}