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

时间:2014-03-31 19:24:05

标签: c++ windows dll compiler-construction mingw

我正在使用MinGW-Builds在64位系统上编译32位DLL和exe。我正在使用m32位标志。编译和链接阶段不会产生错误。当我尝试运行程序时,我得到:

  

应用程序无法正确启动(0xc000007b)。单击“确定”关闭应用程序。

我加载了Dependency Walker,我收到以下错误消息:

  

错误:找到了具有不同CPU类型的模块。

确实,Dependency walker显示我的DLL和可执行文件是32位的。但是,它链接的所有其他内容都是64位。例如,NTDLL.DLL,MSVCRT.DLL,LIBWINPTHREAD-1.DLL都标记为64位。所以,我相信我没有正确地链接32位DLL。

让链接器链接到32位DLL而不是64位DLL的命令是什么?

更新

当我运行32位Dependency Walker配置文件模式时,我到底在想什么?我在日志窗口中得到了这个输出:

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

2 个答案:

答案 0 :(得分:1)

当你链接DLL时,你没有指定DLL的位数。您只需指定DLL的名称。它由加载器来查找具有您指定名称的DLL。

您命名的两个DLL,即ntdll和msvcrt,都是系统组件。它们驻留在system32目录中。您的32位进程受文件系统重定向程序的约束。这意味着当加载程序在system32中查找时,重定向程序会以静默方式将其映射到32位系统目录syswow64。这是透明的,因此加载器将找到32位版本的ntdll和msvcrt。

您报告的错误代码为0xC000007B。这是一个NTSTATUS错误代码。具体来说是STATUS_INVALID_IMAGE_FORMAT。当您尝试在32位进程中加载​​64位DLL时,确实报告了错误。所以这似乎正是发生的事情。

您已使用Dependency Walker进行了一些调试。这是一个很好的工具,但在你使用它(静态模式)的模式下,它有时会报告误报。听起来你正在使用64位版本的Dependency Walker。使用32位版本可能会获得更好的诊断。

所有这一切,你真正需要做的是在Dependency Walker的Profile模式下运行你的程序。可以在“配置文件”菜单下找到。执行此操作时,您将从加载程序中获取诊断流,包括无法加载错误STATUS_INVALID_IMAGE_FORMAT的DLL的名称。在那一点上,应该清楚出现了什么问题。

答案 1 :(得分:0)

您正在使用Dependency Walker错误。

64位版本的Dependency Walker不够智能,无法搜索32位DLL路径(David的答案解释了当程序运行时,如何通过重定向实际使用这些路径)。

您需要使用32位Dependency Walker来分析32位代码。