Skip to main content

dobby_rs_framework/framework/
module.rs

1use crate::{Error, Result};
2use core::ffi::{CStr, c_void};
3use std::ffi::CString;
4
5pub struct ModuleHandle {
6    lib_name: CString,
7    raw: *mut c_void,
8}
9
10impl ModuleHandle {
11    pub fn open(lib_name: &str) -> Result<Self> {
12        let lib_name = CString::new(lib_name).map_err(|_| Error::InvalidInput)?;
13        let raw = unsafe { open_module(lib_name.as_c_str()) };
14        if raw.is_null() {
15            return Err(Error::SymbolNotFound);
16        }
17        Ok(Self { lib_name, raw })
18    }
19    pub fn lib_name(&self) -> &str {
20        self.lib_name.to_str().unwrap_or("")
21    }
22    pub fn lib_name_cstr(&self) -> &CStr {
23        self.lib_name.as_c_str()
24    }
25    pub fn raw(&self) -> *mut c_void {
26        self.raw
27    }
28    pub fn resolve(&self, symbol: &CStr) -> Option<*mut c_void> {
29        let p = unsafe { resolve_in_module(self.raw, symbol) };
30        if p.is_null() { None } else { Some(p) }
31    }
32    pub fn wrapped_sym(&self, symbol: &str) -> Option<*mut c_void> {
33        let c = CString::new(symbol).ok()?;
34        self.resolve(c.as_c_str())
35    }
36}
37
38#[cfg(unix)]
39unsafe fn open_module(lib_name: &CStr) -> *mut c_void {
40    libc::dlopen(lib_name.as_ptr(), libc::RTLD_NOW)
41}
42#[cfg(unix)]
43unsafe fn resolve_in_module(module: *mut c_void, symbol: &CStr) -> *mut c_void {
44    libc::dlsym(module, symbol.as_ptr())
45}
46
47#[cfg(windows)]
48unsafe fn open_module(lib_name: &CStr) -> *mut c_void {
49    use windows_sys::Win32::System::LibraryLoader::{GetModuleHandleA, LoadLibraryA};
50    let h = GetModuleHandleA(lib_name.as_ptr() as *const u8);
51    if h.is_null() {
52        LoadLibraryA(lib_name.as_ptr() as *const u8)
53    } else {
54        h
55    }
56}
57#[cfg(windows)]
58unsafe fn resolve_in_module(module: *mut c_void, symbol: &CStr) -> *mut c_void {
59    use windows_sys::Win32::System::LibraryLoader::GetProcAddress;
60    match GetProcAddress(module, symbol.as_ptr() as *const u8) {
61        Some(p) => p as *const () as *mut c_void,
62        None => core::ptr::null_mut(),
63    }
64}