libloader/lib.rs
1pub use libloading;
2
3#[macro_export]
4/// ## Get a function from a dynamic link library
5/// *You need `use libloader::libloading` first*
6/// * `lib_path`: the path of DLL
7/// * `fn_name`: The function name from dll
8/// * `call_name`: The call function name of `fn_name`
9/// * `ret`: return type of the function **if the function don't have return value, use "()" instead**
10/// * `(value: type)`: **(variadic argument)** The arguments of the function from dll
11///
12/// ## Example
13/// ```rust
14/// get_libfn!("libstd.dylib", "println", my_println, (), str: &str);
15/// my_println("Hello World");
16///
17/// get_libfn!("libstd.dylib", "add", my_add, usize, a: usize, b: usize);
18/// println!("10 + 20 = {}", my_add(10, 20));
19///
20/// get_libfn!("libstd.dylib", "print_hello", my_print_hello, ());
21/// my_print_hello();
22/// ```
23/// ### the contents of libstd.dylib:
24/// ```rust
25/// #[no_mangle]
26/// pub fn println(str: &str) {
27/// println!("{}", str);
28/// }
29/// #[no_mangle]
30/// pub fn add(a: usize, b: usize) -> usize {
31/// a + b
32/// }
33/// #[no_mangle]
34/// pub fn print_hello() {
35/// println!("Hello");
36/// }
37/// ```
38macro_rules! get_libfn {
39 ($lib_path: expr, $fn_name: expr, $call_name: ident, $ret: ty, $($v: ident: $t:ty),*) => {
40 pub fn $call_name($($v: $t),*) -> $ret {
41 unsafe {
42 let lib = libloading::Library::new($lib_path).unwrap();
43 let func: libloading::Symbol<fn($($t,)*) -> $ret> = lib.get($fn_name.as_bytes()).unwrap();
44 func($($v,)*)
45 }
46 }
47 };
48 ($lib_path: expr, $fn_name: expr, $call_name:ident, $ret: ty) => {
49 pub fn $call_name() -> $ret {
50 unsafe {
51 let lib = libloading::Library::new($lib_path).unwrap();
52 let func: libloading::Symbol<fn() -> $ret> = lib.get($fn_name.as_bytes()).unwrap();
53 func()
54 }
55 }
56 };
57}
58
59#[cfg(test)]
60mod tests {
61 #[test]
62 fn test_get_libfn() {
63 get_libfn!("libstd.dylib", "println", my_println, (), str: &str);
64 my_println("Hello World");
65
66 get_libfn!("libstd.dylib", "add", my_add, usize, a: usize, b: usize);
67 println!("10 + 20 = {}", my_add(10, 20));
68
69 get_libfn!("libstd.dylib", "print_hello", my_print_hello, ());
70 my_print_hello();
71 }
72}