The metadata indicates the name of the DLL that exports the given function, but Rust doesn't yet support DLL imports and expects a LIB file to resolve those imports. If you have the Windows SDK installed, there will usually be a LIB file by the right name that Rust can use but this is not guaranteed. There are a few edge cases where this doesn't quite line up. I considered generating my own LIB files for the windows crate but we have some folks looking into implementing DLL imports for Rust and I'm hopeful that will arrive soon.
One workaround is to generate and provide your own lib files. This process is briefly described here.
Another workaround is to copy the declaration just for the function in question and change the name of the lib to match a suitable lib that does support the function. The msdn docs usually have the correct name of a lib.
The second workaround seems easier but unfortunately I do not see how to it. Could you provide some guidance?
Hang in there - I'm adding a workaround that should fix this up while we wait for the eventual solution.
I applied a workaround - do let me know if that help. https://github.com/microsoft/windows-rs/pull/465
I ran into linker issues when trying to use the HasExpandedResources API. Here's my code:
mod bindings {
::windows::include_bindings!();
}
use bindings::{
windows::win32::game_mode::*,
};
fn main() {
unsafe {
let mut game_mode: i32 = 0;
let error = HasExpandedResources(&mut game_mode);
if error.is_ok() {
println!("Running in game mode: {}", game_mode != 0);
}
}
Linker says:
...
= note: LINK : fatal error LNK1181: cannot open input file 'api-ms-win-gaming-expandedresources-l1-1-0.lib'
The docs for this function say to link against WindowsApp.lib though, so not sure why that API set ends up here...
Thanks for the repro - I'll update the workaround to cover this.
A more comprehensive workaround is now in place to deal with the linker issue. You should now be able to use this function without issue.
I applied a workaround - do let me know if that help. #465
It does build now, thank you!
I applied a workaround - do let me know if that help. #465
It does build now, thank you!
It doesn't run though. Program tries to load a DLL with the wrong name and crashes.
Can you elaborate? I added a test for the function you mentioned. It does load and run successfully.
You can use dumpbin /imports name.exe to list the imports for each DLL. It also depends on which OS you're running on. The workaround relies on the umbrella libs, which can be problematic but should work reliably on the latest version of Windows with the latest Windows SDK and the latest Visual C++ linker.
Here the dumpbin output:
C:\Windows\system32\cmd.exe /c (dumpbin.exe /imports target\debug\minidump.exe)
Microsoft (R) COFF/PE Dumper Version 14.16.27045.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file target\debug\minidump.exe
File Type: EXECUTABLE IMAGE
Section contains the following imports:
KERNEL32.dll
140029000 Import Address Table
140033540 Import Name Table
0 time date stamp
0 Index of first forwarder reference
410 OpenProcess
57B SetUnhandledExceptionFilter
5BC UnhandledExceptionFilter
382 IsDebuggerPresent
267 GetLastError
36C InitializeSListHead
222 GetCurrentThreadId
4DA RtlLookupFunctionEntry
620 WriteConsoleW
202 GetConsoleMode
DD CreatePipe
4E1 RtlVirtualUnwind
86 CloseHandle
2F0 GetSystemTimeAsFileTime
2D9 GetStdHandle
27E GetModuleHandleW
D7 CreateMutexA
3C4 LoadLibraryA
5E7 WaitForSingleObjectEx
13 AddVectoredExceptionHandler
355 HeapReAlloc
5AC TlsAlloc
5AF TlsSetValue
5AE TlsGetValue
450 QueryPerformanceCounter
21E GetCurrentProcessId
135 EnterCriticalSection
621 WriteFile
240 GetEnvironmentVariableW
217 GetCurrentDirectoryW
53F SetLastError
4D3 RtlCaptureContext
221 GetCurrentThread
21D GetCurrentProcess
111 DeleteCriticalSection
4B4 ReleaseMutex
3C0 LeaveCriticalSection
5B5 TryEnterCriticalSection
367 InitializeCriticalSection
1AD FormatMessageW
352 HeapFree
34E HeapAlloc
2BB GetProcessHeap
2B5 GetProcAddress
389 IsProcessorFeaturePresent
api-ms-win-core-debug-minidump-l1-1-0.dll
1400291D8 Import Address Table
140033718 Import Name Table
0 time date stamp
0 Index of first forwarder reference
1 MiniDumpWriteDump
OLEAUT32.dll
140029170 Import Address Table
1400336B0 Import Name Table
0 time date stamp
0 Index of first forwarder reference
Ordinal 7
Ordinal 6
VCRUNTIME140.dll
140029188 Import Address Table
1400336C8 Import Name Table
0 time date stamp
0 Index of first forwarder reference
3E memset
3D memmove
1 _CxxThrowException
8 __C_specific_handler
3C memcpy
3B memcmp
1B __current_exception
1C __current_exception_context
E __CxxFrameHandler3
api-ms-win-crt-runtime-l1-1-0.dll
140029220 Import Address Table
140033760 Import Name Table
0 time date stamp
0 Index of first forwarder reference
18 _configure_narrow_argv
33 _initialize_narrow_environment
28 _get_initial_narrow_environment
36 _initterm
37 _initterm_e
55 exit
23 _exit
42 _set_app_type
4 __p___argc
5 __p___argv
16 _cexit
15 _c_exit
40 _seh_filter_exe
1E _crt_atexit
34 _initialize_onexit_table
67 terminate
3D _register_thread_local_exe_atexit_callback
3C _register_onexit_function
api-ms-win-crt-math-l1-1-0.dll
140029210 Import Address Table
140033750 Import Name Table
0 time date stamp
0 Index of first forwarder reference
9 __setusermatherr
api-ms-win-crt-stdio-l1-1-0.dll
1400292B8 Import Address Table
1400337F8 Import Name Table
0 time date stamp
0 Index of first forwarder reference
54 _set_fmode
1 __p__commode
api-ms-win-crt-locale-l1-1-0.dll
140029200 Import Address Table
140033740 Import Name Table
0 time date stamp
0 Index of first forwarder reference
8 _configthreadlocale
api-ms-win-crt-heap-l1-1-0.dll
1400291E8 Import Address Table
140033728 Import Name Table
0 time date stamp
0 Index of first forwarder reference
18 free
16 _set_new_mode
Summary
1000 .data
3000 .pdata
B000 .rdata
1000 .reloc
28000 .text
Hit any key to close this window...
As you see it is linked against api-ms-win-core-debug-minidump-l1-1-0.dll where I would have expected DbgHelp.dll or DbgCore.dll according to the documentation.
I am running Win7 on this development machine. But it does have Visual Studio 2019 and tools. Would that explain it? If so will that be the same the future (keep relying on this "proxy" libs/dlls) or is it only temporary due to the workaround and will bind against native libs when the project matures?
Ah, so that would work on Windows 10. The loader figures out how to redirect the call from the api set DLL to the actual DLL. We don't support Windows 7 and I encourage you to upgrade.
I have however requested the metadata refer to the actual DLLs rather than the API set DLLs to make the metadata more compatible with older versions of Windows. That combined with DLL imports mentioned above and this should just work on older versions of Windows.
Thank you! Is there a way I could edit the metadata used for my project manually in the meantime?
You can create your own .winmd with the definitions you need, a unique namespace with a single definition of MiniDumpWriteDump with a different DLL name to match the LIB name that will link to the original DLL. That would work as far as windows-rs is concerned, but creating it is a little complicated.
Part of #81 is allowing you to define metadata directly in Rust. At that point you'd also be able to define the MiniDumpWriteDump function directly in Rust without the need for metadata, but that may be a while.
But probably the simplest solution is to plead with @sotteson1 to make sure MiniDumpWriteDump is included in the fix for https://github.com/microsoft/win32metadata/issues/92. 馃槈
I'm having a similar issue LINK failure with calling functions in the following namespace windows::win32::net_management::*. Specifically, NetGroupEnum (and Ilk) Not sure if your fix can address this; but the failures occur when trying to resolving samcli.lib and wkscli.lib.
Something in:
windows::win32::windows_programming::*
Causes fatal error LNK1181: cannot open input file 'APPHELP.lib'.
(I know that using * is not probably advised, but it's currently only way to get some sort of autocompletion working.)
Here's the PR to ultimately solve this issue in the Rust compiler: https://github.com/rust-lang/rust/pull/84171
Here's the PR to ultimately solve this issue in the Rust compiler: rust-lang/rust#84171
To clarify, that's the first of several PRs that will be necessary to solve this problem for the general case. The umbrella issue (rust-lang/rust#58713) is probably a better place to track the progress of this work.