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}