azure_kinect_sys/
loader.rs

1use crate::Error;
2use std::ffi::c_void;
3use std::ptr;
4
5#[link(name = "kernel32")]
6extern "system" {
7    fn GetLastError() -> u32;
8    fn LoadLibraryExW(
9        lpLibFileName: *const u16,
10        hFile: *const c_void,
11        dwFlags: u32,
12    ) -> *const c_void;
13    fn FreeLibrary(hLibModule: *const c_void) -> i32;
14    fn GetProcAddress(hModule: *const c_void, lpProcName: *const u8) -> *const c_void;
15    fn GetModuleHandleW(lpModuleName: *const u16) -> *const c_void;
16}
17
18pub(crate) struct Module {
19    handle: *const c_void,
20    require_free_library: bool,
21}
22
23impl Drop for Module {
24    fn drop(&mut self) {
25        if self.require_free_library && self.handle != ptr::null() {
26            unsafe {
27                FreeLibrary(self.handle);
28            }
29            self.handle = ptr::null();
30        }
31    }
32}
33
34impl Module {
35    pub fn new(handle: *const c_void, require_free_library: bool) -> Module {
36        Module {
37            handle,
38            require_free_library,
39        }
40    }
41
42    pub fn load_library(lib_dir: &str, dll_file_name: &str) -> Result<Module, Error> {
43        let full_path =
44            std::path::Path::new(if lib_dir.len() > 0 { lib_dir } else { "." }).join(dll_file_name);
45
46        unsafe {
47            let p = LoadLibraryExW(
48                full_path
49                    .to_str()
50                    .ok_or(Error::Failed)?
51                    .encode_utf16()
52                    .chain(Some(0))
53                    .collect::<Vec<u16>>()
54                    .as_ptr(),
55                ptr::null(),
56                0x000,
57            );
58            if p != ptr::null() {
59                Ok(Module::new(p, true))
60            } else {
61                Err(Error::Win32Error(GetLastError()))
62            }
63        }
64    }
65
66    pub fn get_module(module_name: &str) -> Result<Module, Error> {
67        unsafe {
68            let p = GetModuleHandleW(
69                module_name
70                    .encode_utf16()
71                    .chain(Some(0))
72                    .collect::<Vec<u16>>()
73                    .as_ptr(),
74            );
75            if p != ptr::null() {
76                Ok(Module::new(p, false))
77            } else {
78                Err(Error::Win32Error(GetLastError()))
79            }
80        }
81    }
82
83    pub fn get_proc_address(&self, proc_name: *const u8) -> Result<*const c_void, Error> {
84        unsafe {
85            let p = GetProcAddress(self.handle, proc_name);
86            if p != ptr::null() {
87                Ok(p)
88            } else {
89                Err(Error::Win32Error(GetLastError()))
90            }
91        }
92    }
93}