use super::super::err::Error;
use std::ffi::{CStr, CString, OsStr};
#[cfg(unix)]
use super::unix::{close_lib, get_sym, open_self, open_lib, addr_info_obtain, addr_info_init, addr_info_cleanup, Handle};
#[cfg(windows)]
use super::windows::{close_lib, get_sym, open_self, open_lib, addr_info_obtain, addr_info_init, addr_info_cleanup, Handle};
use std::mem::{size_of, transmute_copy};
#[derive(Debug)]
pub struct Library {
handle: Handle,
}
impl Library {
pub fn open<S>(name: S) -> Result<Library, Error>
where
S: AsRef<OsStr>,
{
Ok(Self {
handle: unsafe { open_lib(name.as_ref()) }?,
})
}
pub fn open_self() -> Result<Library, Error> {
Ok(Self {
handle: unsafe { open_self() }?,
})
}
pub unsafe fn symbol<T>(&self, name: &str) -> Result<T, Error> {
let cname = CString::new(name)?;
self.symbol_cstr(cname.as_ref())
}
pub unsafe fn symbol_cstr<T>(&self, name: &CStr) -> Result<T, Error> {
if size_of::<T>() != size_of::<*mut ()>() {
panic!(
"The type passed to dlopen::Library::symbol() function has a different size than a \
pointer - cannot transmute"
);
}
let raw = get_sym(self.handle, name)?;
if raw.is_null() {
return Err(Error::NullSymbol);
} else {
Ok(transmute_copy(&raw))
}
}
}
impl Drop for Library {
fn drop(&mut self) {
self.handle = close_lib(self.handle);
}
}
unsafe impl Sync for Library {}
unsafe impl Send for Library {}
#[derive(Debug)]
pub struct OverlappingSymbol{
pub name: String,
pub addr: * const ()
}
#[derive(Debug)]
pub struct AddressInfo {
pub dll_path: String,
pub dll_base_addr: * const (),
pub overlapping_symbol: Option<OverlappingSymbol>
}
pub struct AddressInfoObtainer {
}
impl AddressInfoObtainer {
pub fn new() -> AddressInfoObtainer {
unsafe{addr_info_init()};
AddressInfoObtainer{}
}
pub fn obtain(&self, addr: * const ()) -> Result<AddressInfo, Error>{
unsafe {addr_info_obtain(addr)}
}
}
impl Drop for AddressInfoObtainer{
fn drop(&mut self) {
unsafe{addr_info_cleanup()}
}
}