#![cfg(any(unix, windows))]
use crate::{
core::{optional::NSTDOptional, str::NSTDStr},
NSTDAny, NSTDAnyMut, NSTDChar,
};
use cfg_if::cfg_if;
use nstdapi::nstdapi;
cfg_if! {
if #[cfg(unix)] {
use crate::{
alloc::NSTD_ALLOCATOR,
core::{
cstr::{nstd_core_cstr_as_ptr, nstd_core_cstr_get_null},
str::nstd_core_str_as_cstr,
},
cstring::{nstd_cstring_as_ptr, nstd_cstring_from_cstr_unchecked},
};
use libc::{dlclose, dlopen, dlsym, RTLD_LAZY, RTLD_LOCAL};
#[nstdapi]
pub struct NSTDSharedLib {
handle: NSTDAnyMut,
}
impl Drop for NSTDSharedLib {
#[inline]
fn drop(&mut self) {
unsafe { dlclose(self.handle) };
}
}
unsafe impl Send for NSTDSharedLib {}
unsafe impl Sync for NSTDSharedLib {}
} else if #[cfg(windows)] {
use crate::{
os::windows::{
shared_lib::{
nstd_os_windows_shared_lib_get, nstd_os_windows_shared_lib_get_mut,
nstd_os_windows_shared_lib_load, NSTDWindowsSharedLib,
},
str::nstd_os_windows_str_to_utf16,
},
vec::nstd_vec_as_ptr,
};
pub type NSTDSharedLib = NSTDWindowsSharedLib;
}
}
pub type NSTDOptionalSharedLib = NSTDOptional<NSTDSharedLib>;
#[nstdapi]
pub unsafe fn nstd_shared_lib_load(path: &NSTDStr) -> NSTDOptionalSharedLib {
#[cfg(unix)]
{
let path = nstd_core_str_as_cstr(path);
if nstd_core_cstr_get_null(&path).is_null() {
if let NSTDOptional::Some(path) =
nstd_cstring_from_cstr_unchecked(&NSTD_ALLOCATOR, &path)
{
let handle = dlopen(nstd_cstring_as_ptr(&path), RTLD_LAZY | RTLD_LOCAL);
if !handle.is_null() {
return NSTDOptional::Some(NSTDSharedLib { handle });
}
}
NSTDOptional::None
} else {
let handle = dlopen(nstd_core_cstr_as_ptr(&path), RTLD_LAZY | RTLD_LOCAL);
match !handle.is_null() {
true => NSTDOptional::Some(NSTDSharedLib { handle }),
false => NSTDOptional::None,
}
}
}
#[cfg(windows)]
{
let NSTDOptional::Some(utf16) = nstd_os_windows_str_to_utf16(path) else {
return NSTDOptional::None;
};
nstd_os_windows_shared_lib_load(nstd_vec_as_ptr(&utf16).cast())
}
}
#[inline]
#[nstdapi]
pub unsafe fn nstd_shared_lib_get(lib: &NSTDSharedLib, symbol: *const NSTDChar) -> NSTDAny {
#[cfg(unix)]
return dlsym(lib.handle, symbol);
#[cfg(windows)]
return nstd_os_windows_shared_lib_get(lib, symbol);
}
#[inline]
#[nstdapi]
pub unsafe fn nstd_shared_lib_get_mut(
lib: &mut NSTDSharedLib,
symbol: *const NSTDChar,
) -> NSTDAnyMut {
#[cfg(unix)]
return dlsym(lib.handle, symbol);
#[cfg(windows)]
return nstd_os_windows_shared_lib_get_mut(lib, symbol);
}
#[inline]
#[nstdapi]
#[allow(
unused_variables,
clippy::missing_const_for_fn,
clippy::needless_pass_by_value
)]
pub fn nstd_shared_lib_free(lib: NSTDSharedLib) {}