-
Notifications
You must be signed in to change notification settings - Fork 585
Description
Suggestion
As shown in the delay load sample here, windows-rs provides the ability to dynamically load Windows Win32 APIs at runtime with GetProcAddress
.
However if a developer wants to dynamically load an API, the developer needs to copy-paste the function signature even though windows-sys already knows the signature that needs to be used here (since it used that signature to generate the bindings in the first place).
From the delay_load example, Kenny had to re-declare ShellMessageBoxW's signature even though windows-rs "already knows" that signature since it generates the function signature already for linking against:
type ShellMessageBoxW = unsafe extern "C" fn(
happinst: usize,
hwnd: usize,
lpctext: PCWSTR,
lpctitle: PCWSTR,
fustyle: u32,
...
) -> i32;
// vs this generated from windows_sys
windows_link::link!("shlwapi.dll" "C" fn ShellMessageBoxW(happinst : super::super::Foundation:: HINSTANCE, hwnd : super::super::Foundation:: HWND, lpctext : windows_sys::core::PCWSTR, lpctitle : windows_sys::core::PCWSTR, fustyle : super::WindowsAndMessaging:: MESSAGEBOX_STYLE, ...) -> i32);
I propose that windows-sys (or the bindings generation code only) provide an option to generate function pointer types along side the sys
style windows_link
bindings for the dynamic loading scenarios. This would allow Rust app developers to load Windows functionality at runtime without having to copy-paste the windows-sys generated bindings and hand-edit them from raw-dylib
bindings into the function pointer types they want to use.
The binding generation code could look something like this in my head:
windows_link::link!("shlwapi.dll" "C" fn ShellMessageBoxW(happinst : super::super::Foundation:: HINSTANCE, hwnd : super::super::Foundation:: HWND, lpctext : windows_sys::core::PCWSTR, lpctitle : windows_sys::core::PCWSTR, fustyle : super::WindowsAndMessaging:: MESSAGEBOX_STYLE, ...) -> i32);
type ShellMessageBoxWFn = unsafe extern "C" fn(happinst : super::super::Foundation:: HINSTANCE, hwnd : super::super::Foundation:: HWND, lpctext : windows_sys::core::PCWSTR, lpctitle : windows_sys::core::PCWSTR, fustyle : super::WindowsAndMessaging:: MESSAGEBOX_STYLE, ...) -> i32);
The real world use case is that many app developers rely on dynamic loading of Windows APIs in order to allow for a single binary to run across both new and old versions of Windows that may or may not have a DLL export for a given API. Without this dynamic loading behavior using GetProcAddress and function pointers, on older versions of Windows that don't have a DLL export for a function, you'd get an error similar to this one:

I have started and stopped a few times trying to implement this feature myself. Maybe I'll still find time to do that soon, but in the mean time I thought I'd open this feature request for tracking in case someone else can easily implement this before I get the chance to, and if I'm barking up the wrong tree here for some reason it would be useful to know that early before I go too far down the rabbit hole :).