dlib::dlopen_external_library! [] [src]

macro_rules! dlopen_external_library(
    (__struct, $structname: ident,
        $(statics: $($sname: ident: $stype: ty),+)|*
        $(functions: $(fn $fname: ident($($farg: ty),*) -> $fret:ty),+)|*
        $(varargs: $(fn $vname: ident($($vargs: ty),+ ...) -> $vret: ty),+)|*
    ) => (
        pub struct $structname {
            $($(
                pub $sname: &'static $stype,
            )+)*
            $($(
                pub $fname: unsafe extern fn($($farg),*) -> $fret,
            )+)*
            $($(
                pub $vname: unsafe extern "C" fn($($vargs),+ , ...) -> $vret,
            )+)*
        }
    );
    (__impl, $structname: ident,
        $(statics: $($sname: ident: $stype: ty),+)|*
        $(functions: $(fn $fname: ident($($farg: ty),*) -> $fret:ty),+)|*
        $(varargs: $(fn $vname: ident($($vargs: ty),+ ...) -> $vret: ty),+)|*
    ) => (
    impl $structname {
        pub fn open(name: &str) -> Result<$structname, $crate::DlError> {
            let cname = match ::std::ffi::CString::new(name) {
                Ok(cs) => cs,
                Err(_) => return Err($crate::DlError::NotFound)
            };
            unsafe {
                let dl = $crate::ffi::dlopen(cname.as_bytes_with_nul().as_ptr() as *const _, 1);
                if dl.is_null() {
                    return Err($crate::DlError::NotFound);
                }
                $crate::ffi::dlerror();
                let s = $structname {
                    $($($sname: {
                        let s_name = concat!(stringify!($sname), "\0");
                        let symbol = $crate::ffi::dlsym(dl, s_name.as_ptr() as *const _);
                        if !$crate::ffi::dlerror().is_null() {
                            return Err($crate::DlError::MissingSymbol(s_name))
                        }
                        ::std::mem::transmute(symbol)
                    },
                    )+)*
                    $($($fname: {
                        let s_name = concat!(stringify!($fname), "\0");
                        let symbol = $crate::ffi::dlsym(dl, s_name.as_ptr() as *const _);
                        if !$crate::ffi::dlerror().is_null() {
                            return Err($crate::DlError::MissingSymbol(s_name))
                        }
                        ::std::mem::transmute(symbol)
                    },
                    )+)*
                    $($($vname: {
                        let s_name = concat!(stringify!($vname), "\0");
                        let symbol = $crate::ffi::dlsym(dl, s_name.as_ptr() as *const _);
                        if !$crate::ffi::dlerror().is_null() {
                            return Err($crate::DlError::MissingSymbol(s_name))
                        }
                        ::std::mem::transmute(symbol)
                    },
                    )+)*
                };
                Ok(s)
            }
        }
    }
    );
    ($structname: ident,
        $(statics: $($sname: ident: $stype: ty),+)|*
        $(functions: $(fn $fname: ident($($farg: ty),*) -> $fret:ty),+)|*
        $(varargs: $(fn $vname: ident($($vargs: ty),+ ...) -> $vret: ty),+)|*
    ) => (
        dlopen_external_library!(__struct,
            $structname, $(statics: $($sname: $stype),+)|*
            $(functions: $(fn $fname($($farg),*) -> $fret),+)|*
            $(varargs: $(fn $vname($($vargs),+ ...) -> $vret),+)|*
        );
        dlopen_external_library!(__impl,
            $structname, $(statics: $($sname: $stype),+)|*
            $(functions: $(fn $fname($($farg),*) -> $fret),+)|*
            $(varargs: $(fn $vname($($vargs),+ ...) -> $vret),+)|*
        );
        unsafe impl Sync for $structname { }
    );
);