简体   繁体   English

使用MinGW-Builds在64位系统上编译32位exe —编译32位exe,但链接到64位DLL

[英]Using MinGW-Builds to compile a 32-bit exe on a 64-bit system — compiles a 32-bit exe but links against 64-bit DLLs

I am using MinGW-Builds to compile a 32-bit DLL and exe on a 64-bit system. 我正在使用MinGW-Builds在64位系统上编译32位DLL和exe。 I am using the m32 bit flag. 我正在使用m32位标志。 The compilation and linkage stage produces no errors. 编译和链接阶段不会产生任何错误。 When I try to run the program, I get: 当我尝试运行该程序时,我得到:

The application was unable to start correctly (0xc000007b). 应用程序无法正确启动(0xc000007b)。 Click OK to close the application. 单击“确定”关闭该应用程序。

I loaded up Dependency Walker and I got the following error message: 我加载了Dependency Walker并收到以下错误消息:

Error: Modules with different CPU types were found. 错误:找到了具有不同CPU类型的模块。

Indeed, Dependency walker shows that my DLL and executable are 32-bit. 确实,Dependency Walker表明我的DLL和可执行文件是32位的。 However, everything else it links against is 64-bit. 但是,它链接的所有其他内容都是64位。 For example, NTDLL.DLL, MSVCRT.DLL, LIBWINPTHREAD-1.DLL are all marked 64-bit. 例如,NTDLL.DLL,MSVCRT.DLL,LIBWINPTHREAD-1.DLL都标记为64位。 So, I believe I am not linking against the 32-bit DLLs correctly. 因此,我相信我没有正确地链接到32位DLL。

What is the command to get the linker to link against the 32-bit DLLs instead of the 64-bit DLLs? 使链接程序链接到32位DLL而不是64位DLL的命令是什么?

Update 更新

What exactly am I looking for when I run the 32-bit Dependency Walker profile mode? 当我运行32位Dependency Walker配置文件模式时,我到底在寻找什么? I get this output in the log window: 我在日志窗口中得到以下输出:

--------------------------------------------------------------------------------
Starting profile on 3/31/2014 at 10:14:41 PM

Operating System: Microsoft Windows NT/2000/XP/2003/Vista based Media Center (64-bit), version 6.01.7601 Service Pack 1
Program Executable: c:\mingw\msys\1.0\home\samuel\projects\bmd2\build\debug\32\testcore\BMD2TESTCORE.EXE
Program Arguments: 
Starting Directory: C:\MinGW\msys\1.0\home\samuel\projects\bmd2\build\debug\32\testcore\
Search Path: C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\MinGW\bin;C:\MinGW\libexec\gcc\x86_64-pc-mingw32\4.7.0;C:\Users\samuel\gcc\bin;C:\Users\samuel\gcc\libexec\gcc\x86_64-pc-mingw32\4.7.0;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Eclipse\adt-bundle\sdk\platform-tools;C:\Program Files\Eclipse\adt-bundle\sdk\tools;C:\Program Files (x86)\QuickTime\QTSystem\;C:\ant\bin;C:\Java\bin;C:\Program Files\TortoiseSVN\bin;C:\Users\samuel\Desktop\work\bmd2\build\debug\lib

Options Selected:
     Simulate ShellExecute by inserting any App Paths directories into the PATH environment variable.
     Log DllMain calls for process attach and process detach messages.
     Log DllMain calls for all other messages, including thread attach and thread detach.
     Hook the process to gather more detailed dependency information.
     Log LoadLibrary function calls.
     Log GetProcAddress function calls.
     Log thread information.
     Use simple thread numbers instead of actual thread IDs.
     Log first chance exceptions.
     Log debug output messages.
     Log a time stamp with each line of log.
     Automatically open and profile child processes.
--------------------------------------------------------------------------------

00:00:00.000: Started "BMD2TESTCORE.EXE" (process 0x1DC) at address 0x00400000 by thread 1.  Successfully hooked module.
00:00:00.000: Loaded "NTDLL.DLL" at address 0x778C0000 by thread 1.  Successfully hooked module.
00:00:00.031: Loaded "KERNEL32.DLL" at address 0x75510000 by thread 1.  Successfully hooked module.
00:00:00.031: Loaded "KERNELBASE.DLL" at address 0x77340000 by thread 1.  Successfully hooked module.
00:00:00.031: DllMain(0x77340000, DLL_PROCESS_ATTACH, 0x00000000) in "KERNELBASE.DLL" called by thread 1.
00:00:00.031: DllMain(0x77340000, DLL_PROCESS_ATTACH, 0x00000000) in "KERNELBASE.DLL" returned 1 (0x1) by thread 1.
00:00:00.031: DllMain(0x75510000, DLL_PROCESS_ATTACH, 0x00000000) in "KERNEL32.DLL" called by thread 1.
00:00:00.046: DllMain(0x75510000, DLL_PROCESS_ATTACH, 0x00000000) in "KERNEL32.DLL" returned 1 (0x1) by thread 1.
00:00:00.046: Injected "DEPENDS.DLL" at address 0x08370000 by thread 1.
00:00:00.078: DllMain(0x08370000, DLL_PROCESS_ATTACH, 0x00000000) in "DEPENDS.DLL" called by thread 1.
00:00:00.093: DllMain(0x08370000, DLL_PROCESS_ATTACH, 0x00000000) in "DEPENDS.DLL" returned 1 (0x1) by thread 1.
00:00:00.093: Loaded "MSVCRT.DLL" at address 0x75C90000 by thread 1.  Successfully hooked module.

You don't specify the bitness of a DLL when you link against it. 链接到DLL时,您无需指定其位数。 You merely specify the name of the DLL. 您只需指定DLL的名称。 It's up to the loader to find the DLLs with the names that you have specified. 由加载器决定具有您指定名称的DLL。

Two of the DLLs that you name, ntdll and msvcrt, are system components. 您命名的两个DLL,ntdll和msvcrt是系统组件。 They reside in the system32 directory. 它们位于system32目录中。 Your 32 bit process is subject to the file system redirector. 您的32位进程受文件系统重定向器的约束。 That means that when the loader looks in system32, the redirector silently maps that to syswow64, the 32 bit system directory. 这意味着,当加载程序在system32中查找时,重定向器会将其静默映射到32位系统目录syswow64。 That happens transparently so the loader will find 32 bit versions of ntdll and msvcrt. 这是透明发生的,因此加载程序将找到32位版本的ntdll和msvcrt。

The error code that you report is 0xC000007B . 您报告的错误代码是0xC000007B That is an NTSTATUS error code. 那是一个NTSTATUS错误代码。 Specifically STATUS_INVALID_IMAGE_FORMAT . 特别是STATUS_INVALID_IMAGE_FORMAT Which is indeed the error reported when you attempt to load a 64 bit DLL in a 32 bit process. 当您尝试在32位进程中加载​​64位DLL时,的确是报告的错误。 So it seems likely that this is what is happening. 因此,这似乎正在发生。

You've done some debugging with Dependency Walker. 您已经使用Dependency Walker进行了一些调试。 This is an excellent tool for the job, but in the mode you have used it in (static mode) it does sometimes report false positives. 这是完成这项工作的出色工具,但是在您以(静态模式)使用它的模式下,有时确实会报告误报。 It sounds like you are using the 64 bit version of Dependency Walker. 听起来您正在使用Dependency Walker的64位版本。 You might get better diagnostics with the 32 bit version. 使用32位版本可能会得到更好的诊断。

All that said, what you really need to do is to run your program under the Profile mode of Dependency Walker. 也就是说,您真正需要做的是在Dependency Walker的Profile模式下运行程序。 That can be found under the Profile menu. 可以在“配置文件”菜单下找到。 When you do this you'll get a stream of diagnostics from the loader, including the name of the DLL that failed to load with error STATUS_INVALID_IMAGE_FORMAT . 执行此操作时,您将从加载程序中获取诊断流,其中包括由于错误STATUS_INVALID_IMAGE_FORMAT而无法加载的DLL的名称。 At that point it should become clear what has gone wrong. 到那时,应该弄清楚出了什么问题。

You're using Dependency Walker wrong. 您使用的Dependency Walker错误。

The 64-bit version of Dependency Walker isn't smart enough to search the 32-bit DLL paths (David's answer explains how these actually get used when your program runs, via redirection). 64位版本的Dependency Walker不够智能,无法搜索32位DLL路径(David的回答说明了如何在程序运行时通过重定向实际使用这些路径)。

You need to use the 32-bit Dependency Walker for analyzing 32-bit code. 您需要使用32位Dependency Walker来分析32位代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM