В программе C/С++, как система (windows, linux, mac OS X) вызывает функцию main() - программирование
Подтвердить что ты не робот

В программе C/С++, как система (windows, linux, mac OS X) вызывает функцию main()

Я ищу более техническое объяснение, тогда ОС вызывает функцию. Может ли кто-нибудь помочь мне или указать мне на сайт или книгу?

4b9b3361

Ответ 1

Файл .exe(или эквивалент на других платформах) содержит адрес "точки входа". В первом приближении ОС загружает соответствующие разделы файла .EXE в ram, а затем переходит к точке входа.

Как говорили другие, эта точка входа не будет "основной", но будет частью библиотеки времени выполнения - она ​​будет делать такие вещи, как инициализация статических объектов, настройка параметров argc/argv, настройка stdin/stdout/stderr и т.д. Когда все это будет сделано, оно вызовет вашу функцию main(). Когда основные выходы, среда выполнения проходит через аналоговый процесс передачи кода возврата обратно в среду, вызывая статические деструкторы, вызывая подпрограммы _atexit и т.д.

Если у вас есть инструменты для MS (возможно, не для халявы), тогда у вас есть весь источник времени выполнения, и простой способ взглянуть на него - это поставить точку останова на закрывающую фигуру вашего метода main() и single шаг назад во время выполнения.

Ответ 2

main() является частью библиотеки C и не является системной функцией. Я не знаю, для OS X или Linux, но Windows обычно запускает программу с WinMainCRTStartup(). Этот символ инициализирует ваш процесс, извлекает аргументы командной строки и среду (argc, argv, end) и вызывает main(). Он также отвечает за вызов любого кода, который должен запускаться после main(), например atexit().

Изучая файл Visual Studio, вы сможете найти реализацию WinMainCRTStartup по умолчанию, чтобы увидеть, что он делает.

Вы также можете определить собственную функцию для вызова при запуске, это делается путем изменения "точки входа" в параметрах компоновщика. Это часто функция, которая не принимает аргументов и возвращает пустоту.

Ответ 3

Что касается окон, то функции входа:

  • Консоль: void __cdecl mainCRTStartup( void ) {}
  • GUI: void __stdcall WinMainCRTStartup( void ) {}
  • DLL: BOOL __stdcall _DllMainCRTStartup(HINSTANCE hinstDLL,DWORD fdwReason,void* lpReserved) {}

Единственная причина использовать их в обычном main/WinMain/DllMain - если вы хотите использовать свою собственную библиотеку времени выполнения (если вы хотите уменьшить размер файла или пользовательские функции)

Для пользовательских реализаций времени выполнения и других трюков для получения меньших PE файлов см.:

Ответ 4

Expert С++/CLI (см. стр. 279) содержит очень конкретные сведения о различных сценариях начальной загрузки для родной, смешанной и чистой CLR узлы.

Ответ 5

Это зависит от ОС. В OS X есть кадр в заголовке mach, который содержит начальный адрес для регистра EIP (указателя инструкции).

После загрузки двоичного файла ОС запускает выполнение с этого адреса:

cristi:test diciu$ otool -l ./a.out | grep -A 10 LC_UNIXTHREAD
        cmd LC_UNIXTHREAD
    cmdsize 80
     flavor i386_THREAD_STATE
      count i386_THREAD_STATE_COUNT
[..]
        ss  0x00000000 eflags 0x00000000 eip 0x00001f8c cs  0x00000000
[..]

Адрес - это адрес функции "start" из двоичного файла:

cristi:test diciu$ nm ./a.out
0000200c D _NXArgc
00002008 D _NXArgv
00002000 D ___progname
00001fe0 t __dyld_func_lookup
00001000 A __mh_execute_header
[..]
00001f8c T start

В Mac OS X это функция "start", которая сначала вызывается, даже до "основной" функции:

(gdb) b start
Breakpoint 1 at 0x1f90
(gdb) b main
Breakpoint 2 at 0x1ff4
(gdb) r
Starting program: /Users/diciu/Programming/test/a.out 
Reading symbols for shared libraries ++. done

Breakpoint 1, 0x00001f90 in start ()

Ответ 7

Если вас интересует книга, связанная с Windows и Win32 API, попробуйте

"Программирование приложений для Microsoft Windows" Джеффри Рихтера.