2025-11-05 22:59:01 -07:00
|
|
|
#[macro_use]
|
|
|
|
|
extern crate log;
|
2025-11-05 15:17:31 -07:00
|
|
|
|
|
|
|
|
use libloading::{Library, Symbol};
|
|
|
|
|
use log::{info, warn};
|
|
|
|
|
use unshell_logger::SetupLogger;
|
2025-11-05 22:59:01 -07:00
|
|
|
use unshell_modules::module_interface;
|
2025-11-05 15:17:31 -07:00
|
|
|
|
|
|
|
|
module_interface! {
|
|
|
|
|
Interface {
|
|
|
|
|
fn test1();
|
|
|
|
|
fn test2();
|
|
|
|
|
fn test3();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-05 22:59:01 -07:00
|
|
|
#[allow(dead_code)]
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
enum ModuleError {
|
|
|
|
|
LibLoadingError(libloading::Error),
|
|
|
|
|
LinkError(String),
|
|
|
|
|
}
|
2025-11-05 15:17:31 -07:00
|
|
|
|
2025-11-05 22:59:01 -07:00
|
|
|
struct Module {
|
|
|
|
|
name: String,
|
|
|
|
|
lib: Library,
|
|
|
|
|
}
|
2025-11-05 15:17:31 -07:00
|
|
|
|
2025-11-05 22:59:01 -07:00
|
|
|
impl Module {
|
|
|
|
|
pub fn new(path: &str) -> Result<Self, ModuleError> {
|
|
|
|
|
let lib = unsafe { Library::new(&path) }.map_err(|e| ModuleError::LibLoadingError(e))?;
|
2025-11-05 15:17:31 -07:00
|
|
|
|
2025-11-05 22:59:01 -07:00
|
|
|
Ok(Self {
|
|
|
|
|
name: path.to_owned(),
|
|
|
|
|
lib,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
pub fn get_symbol<T>(&self, symbol: &[u8]) -> Result<Symbol<'_, T>, ModuleError> {
|
|
|
|
|
let symbol = unsafe { self.lib.get::<T>(symbol) }
|
|
|
|
|
.map_err(|e| ModuleError::LinkError(format!("Failed to load symbol: {}", e)))?;
|
2025-11-05 15:17:31 -07:00
|
|
|
|
2025-11-05 22:59:01 -07:00
|
|
|
Ok(symbol)
|
|
|
|
|
}
|
|
|
|
|
pub fn init_logger(&self) {
|
|
|
|
|
if let Ok(setup_logger) = self.get_symbol::<SetupLogger>(b"setup_logger") {
|
2025-11-05 15:17:31 -07:00
|
|
|
setup_logger(log::logger(), log::max_level()).unwrap();
|
|
|
|
|
} else {
|
|
|
|
|
warn!("setup_logger not found");
|
|
|
|
|
}
|
2025-11-05 22:59:01 -07:00
|
|
|
}
|
|
|
|
|
pub fn get_interface<T>(&self) -> Result<T, ModuleError> {
|
|
|
|
|
if let Ok(interface_function) = self.get_symbol::<fn() -> T>(b"interface") {
|
|
|
|
|
Ok(interface_function())
|
|
|
|
|
} else {
|
|
|
|
|
Err(ModuleError::LinkError(format!(
|
|
|
|
|
"Interface function not found!"
|
|
|
|
|
)))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-05 15:17:31 -07:00
|
|
|
|
2025-11-05 22:59:01 -07:00
|
|
|
fn main() {
|
|
|
|
|
pretty_env_logger::init();
|
2025-11-05 15:17:31 -07:00
|
|
|
|
2025-11-05 22:59:01 -07:00
|
|
|
info!("Initalized");
|
2025-11-05 15:17:31 -07:00
|
|
|
|
2025-11-05 22:59:01 -07:00
|
|
|
match || -> Result<(), ModuleError> {
|
|
|
|
|
let module =
|
|
|
|
|
Module::new("../unshell-module-test/target/release/libunshell_module_test.so")?;
|
|
|
|
|
module.init_logger();
|
2025-11-05 15:17:31 -07:00
|
|
|
|
2025-11-05 22:59:01 -07:00
|
|
|
let interface = module.get_interface::<Interface>()?;
|
2025-11-05 15:17:31 -07:00
|
|
|
|
2025-11-05 22:59:01 -07:00
|
|
|
interface.test1();
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}() {
|
|
|
|
|
Ok(_) => {}
|
|
|
|
|
Err(e) => {
|
|
|
|
|
error!("ERROR! {:?}", e);
|
|
|
|
|
}
|
2025-11-05 15:17:31 -07:00
|
|
|
}
|
|
|
|
|
}
|