1 #[doc(hidden)]
2 #[macro_export]
3 macro_rules! demand_load {
4     ( $( $library:literal {
5         $(fn $sym:ident ( $( $param: ident : $pty: ty ),* $(,)? ) -> $rt: ty;)*
6     } )* ) => {
7         $($(
8             #[allow(non_snake_case)]
9             unsafe fn $sym( $( $param: $pty ),* ) -> ::std::result::Result<$rt, ::windows::runtime::HRESULT> {
10                 static ONCE: ::std::sync::Once = ::std::sync::Once::new();
11                 static mut VALUE: ::std::mem::MaybeUninit<::std::result::Result<::windows::runtime::RawPtr, ::windows::runtime::HRESULT>> =
12                     ::std::mem::MaybeUninit::uninit();
13 
14                 ONCE.call_once(|| {
15                     VALUE = ::std::mem::MaybeUninit::new(
16                         ::windows::runtime::delay_load($library, ::std::stringify!($sym))
17                     )
18                 });
19 
20                 // transmute() doesn't work on generic types, as you can't constrain to a
21                 // function pointer, so it must be done here outside load_proc().
22                 type FnPtr = extern "system" fn ( $( $param: $pty ),* ) -> $rt;
23                 let f = ::std::mem::transmute::<::windows::runtime::RawPtr, FnPtr>(VALUE.assume_init()?);
24                 ::std::result::Result::Ok( (f)( $( $param ),* ) )
25             }
26         )*)*
27     };
28 }
29