# Dynamically load functions from a windows dll Works on extern blocks containing only functions: ```rust # use platform::*; use windows_dll::dll; #[dll("user32.dll")] extern "system" { #[allow(non_snake_case)] fn SetWindowCompositionAttribute(h_wnd: HWND, data: *mut WINDOWCOMPOSITIONATTRIBDATA) -> BOOL; } # # #[allow(non_snake_case)] # type WINDOWCOMPOSITIONATTRIB = u32; # # #[allow(non_snake_case)] # #[repr(C)] # pub struct WINDOWCOMPOSITIONATTRIBDATA { # Attrib: WINDOWCOMPOSITIONATTRIB, # pvData: PVOID, # cbData: SIZE_T, # } # # #[cfg(feature = "winapi")] # mod platform { # pub use winapi::shared::{basetsd::SIZE_T, minwindef::BOOL, ntdef::PVOID, windef::HWND}; # } # # #[cfg(feature = "windows")] # mod platform { # use core::ffi::c_void; # pub use windows::Win32::Foundation::{BOOL, HWND}; # # pub type PVOID = *mut c_void; # #[allow(non_camel_case_types)] # pub type SIZE_T = usize; # } ``` The `.dll` file extension can be omitted if the dll name has no path: ```rust use windows_dll::dll; #[dll("user32")] extern "system" { // ... } ``` if the dll name is a valid rust identifier, you can also omit the quotes: ```rust use windows_dll::dll; #[dll(user32)] extern "system" { // ... } ``` For each function declaration, an unsafe rust wrapper function will be generated which dynamically loads the original function from the dll. ## Rename If you need to give the rust function a different name you can manually specify the dll symbol to load, Just put the dll symbol name in a **`#[link_name]`** attribute: ```rust # use platform::*; use windows_dll::dll; #[dll(user32)] extern "system" { #[link_name = "SetWindowCompositionAttribute"] fn set_window_composition_attribute(h_wnd: HWND, data: *mut WINDOWCOMPOSITIONATTRIBDATA) -> BOOL; } # # #[allow(non_snake_case)] # type WINDOWCOMPOSITIONATTRIB = u32; # # #[allow(non_snake_case)] # #[repr(C)] # pub struct WINDOWCOMPOSITIONATTRIBDATA { # Attrib: WINDOWCOMPOSITIONATTRIB, # pvData: PVOID, # cbData: SIZE_T, # } # # #[cfg(feature = "winapi")] # mod platform { # pub use winapi::shared::{basetsd::SIZE_T, minwindef::BOOL, ntdef::PVOID, windef::HWND}; # } # # #[cfg(feature = "windows")] # mod platform { # use core::ffi::c_void; # pub use windows::Win32::Foundation::{BOOL, HWND}; # # pub type PVOID = *mut c_void; # #[allow(non_camel_case_types)] # pub type SIZE_T = usize; # } ``` ## Ordinal exports If you need to load a function that is exported by ordinal you can put the ordinal in a **`#[link_ordinal]`** attribute: ```rust # use platform::*; use windows_dll::dll; #[dll(uxtheme)] extern "system" { #[link_ordinal = 133] fn allow_dark_mode_for_window(hwnd: HWND, allow: BOOL) -> BOOL; } # # #[cfg(feature = "winapi")] # mod platform { # pub use winapi::shared::{minwindef::BOOL, windef::HWND}; # } # # #[cfg(feature = "windows")] # mod platform { # pub use windows::Win32::Foundation::{BOOL, HWND}; # } ``` ## Error handling By default the generated functions panic when the dll function cannot be loaded you can check if they exist by calling `function_name::exists()` which returns a `bool`: ```rust,no_run # use platform::*; # use windows_dll::dll; # # #[dll(uxtheme)] # extern "system" { # #[link_ordinal = 133] # fn allow_dark_mode_for_window(hwnd: HWND, allow: BOOL) -> BOOL; # } # # #[cfg(feature = "winapi")] # mod platform { # pub use winapi::shared::{minwindef::{BOOL, TRUE}, windef::HWND}; # pub const EXAMPLE_HWND: HWND = core::ptr::null_mut(); # } # # #[cfg(feature = "windows")] # mod platform { # pub use windows::Win32::Foundation::{BOOL, HWND}; # pub const EXAMPLE_HWND: HWND = HWND(0); # pub const TRUE: BOOL = BOOL(1); # } # # let hwnd = EXAMPLE_HWND; # let allow = TRUE; unsafe { if allow_dark_mode_for_window::exists() { allow_dark_mode_for_window(hwnd, allow); } } ``` You can also generate a wrapper function which returns a `Result>` To better integrate with the **`?`** operator, Just put a **`#[fallible]`** attribute on the function declaration: ```rust,no_run # use platform::*; use std::error::Error; use windows_dll::dll; #[dll(user32)] extern "system" { #[allow(non_snake_case)] #[fallible] fn SetWindowCompositionAttribute(h_wnd: HWND, data: *mut WINDOWCOMPOSITIONATTRIBDATA) -> BOOL; } fn main() -> Result<(), Box> { # let hwnd = EXAMPLE_HWND; # let mut is_dark_mode_bigbool = TRUE; # let mut data = WINDOWCOMPOSITIONATTRIBDATA { # Attrib: WCA_USEDARKMODECOLORS, # pvData: &mut is_dark_mode_bigbool as *mut _ as _, # cbData: core::mem::size_of::(), # }; // ... let result: Result> = unsafe { SetWindowCompositionAttribute(hwnd, &mut data) }; let result = result?; // ... # Ok(()) } # # #[allow(non_snake_case)] # type WINDOWCOMPOSITIONATTRIB = u32; # const WCA_USEDARKMODECOLORS: WINDOWCOMPOSITIONATTRIB = 26; # # #[allow(non_snake_case)] # #[repr(C)] # pub struct WINDOWCOMPOSITIONATTRIBDATA { # Attrib: WINDOWCOMPOSITIONATTRIB, # pvData: PVOID, # cbData: SIZE_T, # } # # #[cfg(feature = "winapi")] # mod platform { # pub use winapi::shared::{basetsd::SIZE_T, minwindef::{BOOL, TRUE}, ntdef::PVOID, windef::HWND}; # # pub const EXAMPLE_HWND: HWND = core::ptr::null_mut(); # } # # #[cfg(feature = "windows")] # mod platform { # use core::ffi::c_void; # pub use windows::Win32::Foundation::{BOOL, HWND}; # # pub type PVOID = *mut c_void; # #[allow(non_camel_case_types)] # pub type SIZE_T = usize; # # pub const EXAMPLE_HWND: HWND = HWND(0); # pub const TRUE: BOOL = BOOL(1); # } ``` # LoadLibraryExW flags This library uses the Win32 API function [LoadLibraryExW](https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw) internally. You can pass flags to the dwFlags parameter by passing a second argument to the **`#[dll]`** attribute: ```rust # use platform::*; use windows_dll::{dll, flags::*}; #[dll(bcrypt, LOAD_LIBRARY_SEARCH_SYSTEM32)] extern "system" { #[link_name = "BCryptAddContextFunction"] fn bcrypt_add_context_function(dw_table: ULONG, psz_context: LPCWSTR, dw_interface: ULONG, psz_function: LPCWSTR, dw_position: ULONG) -> BOOL; } # # #[cfg(feature = "winapi")] # mod platform { # pub use winapi::shared::{ # minwindef::{BOOL, ULONG}, # ntdef::LPCWSTR, # }; # } # # #[cfg(feature = "windows")] # mod platform { # pub use windows::{core::PCWSTR as LPCWSTR, Win32::Foundation::BOOL}; # # pub type ULONG = u32; # } ``` Available flags are re-exported from the **`flags`** module