我编译了一个C ++程序,在发布模式下有一个EXE文件。当我在编辑器中打开EXE文件时,我会看到一些文本块,这些块通常是程序中使用的低级函数的名称。
总是说计算机只能理解二进制机器代码。那么,可执行程序文件中这些人类可读文本的存在目的是什么?为什么计算机需要函数名来运行程序?
IDE:Visual Studio 2015 RC
平台:Windows 8.1 x64
编译器命令行选项:
/GS /GL /W3 /Gy /Zc:wchar_t /Zi /Gm- /Ox /Ob2 /sdl
/Fd"x64\Release\vc140.pdb" /Zc:inline /fp:precise /D "_MBCS"
/errorReport:prompt /GT /WX- /Zc:forScope /Gd /Oy /Oi /MD
/Fa"x64\Release\" /EHsc /nologo /Fo"x64\Release\" /Ot
/Fp"x64\Release\<ProjectName>.pch"
链接器命令行选项:
/OUT:"<SolutionPath>\x64\Release\<ProjectName>.exe"
/MANIFEST /LTCG /NXCOMPAT
/PDB:"<SolutionPath>\x64\Release\<ProjectName>.pdb"
/DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib"
"comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib"
"uuid.lib" "odbc32.lib" "odbccp32.lib"
/MACHINE:X64 /OPT:REF /PGD:"<SolutionPath>\x64\Release\<ProjectName>.pgd"
/MANIFESTUAC:"level='asInvoker' uiAccess='false'"
/ManifestFile:"x64\Release\<ProjectName>.exe.intermediate.manifest"
/OPT:ICF /ERRORREPORT:PROMPT /NOLOGO /TLBID:1
我在rcgldr's answer进行了更改。我进行了项目设置更改,将命令行开关\MD
更改为\MT
。可执行文件大小从56kb更改为436kb。我想这是因为现在所需的库在运行时没有链接,但它们从一开始就存储在EXE文件中。但是仍然有EXE文件中的文本块,如下面的屏幕截图所示。标准模板库(STL)中的函数名称已完全消失,但有许多Win32 API函数名称。现在可能是什么原因?
答案 0 :(得分:2)
这些是从.DLL访问的名称。尝试使用静态库构建,这些名称应该消失,但.EXE会变大。为此,对于发布版本,右键单击项目中的源文件名,并将运行时库从“多线程DLL”(/ MD)更改为“多线程(/ MT)”。这里的主要变化是编译器命令行选项/ MD变为/ MT。
然而,正如Peter Torr在下面评论的那样,你仍然遇到了一些dll模块,比如kernel32.dll。
答案 1 :(得分:1)
在Windows上构建的可执行文件使用可移植可执行文件格式:https://msdn.microsoft.com/en-us/library/ms809762.aspx
为了链接到DLL中的函数,使用导入和导出表创建EXE,这些表包含运行时使用的函数的地址。如果将SDK(或VC ++?)实用程序“dumpbin”与/ exports或/ imports一起使用,则可以看到从模块导入或导出的函数。当新版本出来时,DLL的布局可能会发生变化,因此导入和导出表是调用者在另一个动态链接模块中获取函数地址的一种方式。