Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linker error calling certain functions #463

Closed
kennykerr opened this issue Jan 28, 2021 · 19 comments · Fixed by #467 or #977
Closed

Linker error calling certain functions #463

kennykerr opened this issue Jan 28, 2021 · 19 comments · Fixed by #467 or #977
Labels
bug Something isn't working

Comments

@kennykerr
Copy link
Collaborator

kennykerr commented Jan 28, 2021

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.

@DaLynX
Copy link

DaLynX commented Jan 28, 2021

The second workaround seems easier but unfortunately I do not see how to it. Could you provide some guidance?

@kennykerr
Copy link
Collaborator Author

Hang in there - I'm adding a workaround that should fix this up while we wait for the eventual solution.

@kennykerr
Copy link
Collaborator Author

I applied a workaround - do let me know if that help. #465

@CarePackage17
Copy link

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...

@kennykerr
Copy link
Collaborator Author

Thanks for the repro - I'll update the workaround to cover this.

@kennykerr
Copy link
Collaborator Author

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.

@kennykerr kennykerr reopened this Jan 28, 2021
@kennykerr kennykerr unpinned this issue Jan 28, 2021
@DaLynX
Copy link

DaLynX commented Jan 29, 2021

I applied a workaround - do let me know if that help. #465

It does build now, thank you!

@DaLynX
Copy link

DaLynX commented Jan 30, 2021

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.

@kennykerr
Copy link
Collaborator Author

Can you elaborate? I added a test for the function you mentioned. It does load and run successfully.

let result = MiniDumpWriteDump(
HANDLE(0),
0,
HANDLE(0),
MINIDUMP_TYPE::MiniDumpNormal,
std::ptr::null_mut(),
std::ptr::null_mut(),
std::ptr::null_mut(),
);
assert!(result.is_err());

@kennykerr
Copy link
Collaborator Author

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.

@DaLynX
Copy link

DaLynX commented Jan 31, 2021

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?

@kennykerr
Copy link
Collaborator Author

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.

@DaLynX
Copy link

DaLynX commented Jan 31, 2021

Thank you! Is there a way I could edit the metadata used for my project manually in the meantime?

@kennykerr
Copy link
Collaborator Author

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 microsoft/win32metadata#92. 😉

@john-hern
Copy link

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.

@Ciantic
Copy link

Ciantic commented Mar 7, 2021

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.)

@kennykerr
Copy link
Collaborator Author

Here's the PR to ultimately solve this issue in the Rust compiler: rust-lang/rust#84171

@ricobbe
Copy link

ricobbe commented Apr 28, 2021

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.

@zhiburt
Copy link

zhiburt commented Jul 4, 2021

Just a note: (which probably doesn't matter a lot) but adding Windows::Win32::Security::*, to a build.rs file from the example in README.md as well causes this issue LNK1181

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
7 participants