use std::path::Path;
use libloading::{Library, Symbol};
use rlvgl_core::application::Application;
#[allow(improper_ctypes_definitions)]
type CreateFn = unsafe extern "C" fn() -> *mut dyn Application;
#[allow(improper_ctypes_definitions)]
type DestroyFn = unsafe extern "C" fn(*mut dyn Application);
pub struct LoadedApp {
_library: Library,
app: *mut dyn Application,
destroy_fn: DestroyFn,
}
impl LoadedApp {
pub unsafe fn load(path: impl AsRef<Path>) -> Result<Self, libloading::Error> {
unsafe {
let library = Library::new(path.as_ref().as_os_str())?;
let create: Symbol<CreateFn> =
library.get(rlvgl_core::application::CREATE_APP_SYMBOL)?;
let destroy: Symbol<DestroyFn> =
library.get(rlvgl_core::application::DESTROY_APP_SYMBOL)?;
let app = create();
let destroy_fn = *destroy;
Ok(Self {
_library: library,
app,
destroy_fn,
})
}
}
pub fn app(&self) -> &dyn Application {
unsafe { &*self.app }
}
pub fn app_mut(&mut self) -> &mut dyn Application {
unsafe { &mut *self.app }
}
}
impl Drop for LoadedApp {
fn drop(&mut self) {
unsafe {
(self.destroy_fn)(self.app);
}
}
}