makepad_platform/os/linux/
module_loader.rs1use self::super::libc_sys::{dlclose, dlopen, dlsym, RTLD_LAZY, RTLD_LOCAL};
2use std::{ffi::CString, ptr::NonNull};
3
4pub struct ModuleLoader(::std::ptr::NonNull<::std::os::raw::c_void>);
6
7impl ModuleLoader {
8 pub fn load(path: &str) -> Result<Self, ()> {
10 let path = CString::new(path).unwrap();
11
12 let module = unsafe { dlopen(path.as_ptr(), RTLD_LAZY | RTLD_LOCAL) };
14 if module.is_null() {
15 Err(())
16 } else {
17 Ok(ModuleLoader(unsafe { NonNull::new_unchecked(module) }))
18 }
19 }
20
21 pub fn get_symbol<F: Sized>(&self, name: &str) -> Result<F, ()> {
23 let name = CString::new(name).unwrap();
24
25 let symbol = unsafe { dlsym(self.0.as_ptr(), name.as_ptr()) };
26
27 if symbol.is_null() {
28 return Err(());
29 }
30
31 Ok(unsafe { std::mem::transmute_copy::<_, F>(&symbol) })
33 }
34}
35
36impl Drop for ModuleLoader {
37 fn drop(&mut self) {
38 unsafe { dlclose(self.0.as_ptr()) };
40 }
41}