azure-kinect-sys 0.2.0

azure-kinect-sys
Documentation
use crate::Error;
use std::ffi::c_void;
use std::ptr;

#[link(name = "kernel32")]
extern "system" {
    fn GetLastError() -> u32;
    fn LoadLibraryExW(
        lpLibFileName: *const u16,
        hFile: *const c_void,
        dwFlags: u32,
    ) -> *const c_void;
    fn FreeLibrary(hLibModule: *const c_void) -> i32;
    fn GetProcAddress(hModule: *const c_void, lpProcName: *const u8) -> *const c_void;
    fn GetModuleHandleW(lpModuleName: *const u16) -> *const c_void;
}

pub(crate) struct Module {
    handle: *const c_void,
    require_free_library: bool,
}

impl Drop for Module {
    fn drop(&mut self) {
        if self.require_free_library && self.handle != ptr::null() {
            unsafe {
                FreeLibrary(self.handle);
            }
            self.handle = ptr::null();
        }
    }
}

impl Module {
    pub fn new(handle: *const c_void, require_free_library: bool) -> Module {
        Module {
            handle,
            require_free_library,
        }
    }

    pub fn load_library(lib_dir: &str, dll_file_name: &str) -> Result<Module, Error> {
        let full_path =
            std::path::Path::new(if lib_dir.len() > 0 { lib_dir } else { "." }).join(dll_file_name);

        unsafe {
            let p = LoadLibraryExW(
                full_path
                    .to_str()
                    .ok_or(Error::Failed)?
                    .encode_utf16()
                    .chain(Some(0))
                    .collect::<Vec<u16>>()
                    .as_ptr(),
                ptr::null(),
                0x000,
            );
            if p != ptr::null() {
                Ok(Module::new(p, true))
            } else {
                Err(Error::Win32Error(GetLastError()))
            }
        }
    }

    pub fn get_module(module_name: &str) -> Result<Module, Error> {
        unsafe {
            let p = GetModuleHandleW(
                module_name
                    .encode_utf16()
                    .chain(Some(0))
                    .collect::<Vec<u16>>()
                    .as_ptr(),
            );
            if p != ptr::null() {
                Ok(Module::new(p, false))
            } else {
                Err(Error::Win32Error(GetLastError()))
            }
        }
    }

    pub fn get_proc_address(&self, proc_name: *const u8) -> Result<*const c_void, Error> {
        unsafe {
            let p = GetProcAddress(self.handle, proc_name);
            if p != ptr::null() {
                Ok(p)
            } else {
                Err(Error::Win32Error(GetLastError()))
            }
        }
    }
}