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