Я скомпилировал программу на 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. Я внес изменения в настройки проекта, которые изменяют переключатель командной строки \MD
в \MT
, Размер исполняемого файла изменен с 56 КБ до 436 КБ. Я думаю, это потому, что теперь необходимые библиотеки не связаны во время выполнения, но они хранятся в файле EXE с самого начала. Но все же в файле EXE есть блоки текста, как показано на снимке экрана ниже. Имена функций из Стандартной библиотеки шаблонов (STL) полностью исчезли, но существует множество имен функций Win32 API. В чем может быть причина сейчас?
Это имена для доступа из .DLL. Попробуйте построить с использованием статической библиотеки, и эти имена должны исчезнуть, но .EXE станет больше. Для этого при сборке релиза щелкните правой кнопкой мыши по имени файла (ов) в проекте и измените библиотеку времени выполнения с «Многопоточная DLL» (/ MD) на «Многопоточная (/ MT)». Основное изменение здесь — опция командной строки компилятора / MD изменяется на / MT.
Однако, как прокомментировал Питер Торр ниже, вы все еще застряли с некоторыми модулями DLL, такими как kernel32.dll.
Исполняемые файлы, построенные на Windows, использовали формат Portable Executable: https://msdn.microsoft.com/en-us/library/ms809762.aspx
Чтобы связать функции с DLL, создаются EXE-файлы с таблицами импорта и экспорта, которые содержат адреса функций, используемых во время выполнения. Если вы используете утилиту SDK (или VC ++?) «Dumpbin» с / exports или / import, вы можете увидеть функции, которые импортируются или экспортируются из модуля. Расположение новых библиотек DLL может изменяться при появлении новых версий, поэтому таблицы импорта и экспорта позволяют вызывающей стороне получить адрес функции в другом модуле, который динамически связан.