I am using libloading to loading dll, it requires me to confirm the parameter what function need, like this:
let lib = libloading::Library::new("libstd.dylib").unwrap();
let func: Symbol<fn(&str)> = lib.get(b"println").unwrap();
// ^ it requires to confirm the parameter what function need
func("Hello World");
But I want to make a function to call functions from libstd.dylib, Both parameters and types are indeterminate
fn call_from_libstd() {} // I don't know how to implement this function
call_from_libstd("println", "Hello World");
let c = call_from_libstd("add", 10, 20);
println("{}", c);
The functions form dll is like
#[no_mangle]
pub fn println(str: &str) {
println!("{}", str);
}
#[no_mangle]
pub fn add (a: usize,b:usize) -> usize {
return a + b;
}
I solved this problem by macros, and i published my code to crates this is the link.
the main code if:
macro_rules! get_libfn {
($lib_path: expr, $fn_name: expr, $call_name: ident, $ret: ty, $($v: ident: $t:ty),*) => {
pub fn $call_name($($v: $t),*) -> $ret {
unsafe {
let lib = libloading::Library::new($lib_path).unwrap();
let func: libloading::Symbol<fn($($t,)*) -> $ret> = lib.get($fn_name.as_bytes()).unwrap();
func($($v,)*)
}
}
};
($lib_path: expr, $fn_name: expr, $call_name:ident, $ret: ty) => {
pub fn $call_name() -> $ret {
unsafe {
let lib = libloading::Library::new($lib_path).unwrap();
let func: libloading::Symbol<fn() -> $ret> = lib.get($fn_name.as_bytes()).unwrap();
func()
}
}
};
}
get_libfn!("libstd.dylib", "println", my_println, (), str: &str);
my_println("Hello World");