use std::ffi::OsStr;
use std::fmt;
use std::marker;
#[cfg(unix)]
#[macro_use]
extern crate lazy_static;
#[cfg(unix)]
use self::os::unix as imp;
#[cfg(windows)]
use self::os::windows as imp;
pub mod os;
mod util;
pub type Result<T> = ::std::io::Result<T>;
pub struct Library(imp::Library);
impl Library {
pub fn new<P: AsRef<OsStr>>(filename: P) -> Result<Library> {
imp::Library::new(filename).map(Library)
}
pub unsafe fn get<'lib, T>(&'lib self, symbol: &[u8]) -> Result<Symbol<'lib, T>> {
self.0.get(symbol).map(|from| {
Symbol {
inner: from,
pd: marker::PhantomData
}
})
}
}
impl fmt::Debug for Library {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
#[derive(Clone)]
pub struct Symbol<'lib, T: 'lib> {
inner: imp::Symbol<T>,
pd: marker::PhantomData<&'lib T>
}
impl<'lib, T> ::std::ops::Deref for Symbol<'lib, T> {
type Target = T;
fn deref(&self) -> &T {
::std::ops::Deref::deref(&self.inner)
}
}
impl<'lib, T> fmt::Debug for Symbol<'lib, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
#[cfg(all(unix, not(any(target_os="macos", target_os="ios", target_os="android"))))]
#[test]
fn libm() {
let lib = Library::new("libm.so.6").unwrap();
let sin: Symbol<unsafe extern fn(f64) -> f64> = unsafe {
lib.get(b"sin").unwrap()
};
assert!(unsafe { sin(::std::f64::INFINITY) }.is_nan());
let errno: Symbol<*mut u32> = unsafe {
lib.get(b"errno").unwrap()
};
assert!(unsafe { **errno } != 0);
unsafe { **errno = 0; }
}