在C/C++程序中系统(windows、linux、mac OS X)如何调用main()函数

StackOverflow https://stackoverflow.com/questions/12332

  •  08-06-2019
  •  | 
  •  

我正在寻找比操作系统调用该函数更技术性的解释。任何人都可以帮助我或向我指出网站或书籍吗?

有帮助吗?

解决方案

.exe 文件(或其他平台上的等效文件)包含一个“入口点”地址。初步估计,操作系统将 .EXE 文件的相关部分加载到 RAM 中,然后跳转到入口点。

正如其他人所说,这个入口点不会是“main”,而是成为运行时库的一部分 - 它将执行初始化静态对象、设置 argc/argv 参数、设置 stdin/stdout/stderr 等操作, ETC。完成所有这些后,它将调用您的 main() 函数。当 main 退出时,运行时会经历一个类似的过程,将返回代码传递回环境、调用静态析构函数、调用 _atexit 例程等。

如果您有 MS 工具(也许不是免费工具),那么您就拥有所有运行时源,查看它的一个简单方法是在 main() 方法的右大括号上放置一个断点,然后单步备份进入运行时。

其他提示

main() 是 C 库的一部分,不是系统函数。我不知道 OS X 或 Linux,但 Windows 通常启动一个程序 WinMainCRTStartup(). 。该符号初始化您的进程,提取命令行参数和环境(argc, argv, end)并调用 main(). 。它还负责调用应该在之后运行的任何代码 main(), , 喜欢 atexit().

通过查看 Visual Studio 文件,您应该能够找到默认实现 WinMainCRTStartup 看看它做了什么。

您还可以定义自己的函数以在启动时调用,这是通过更改链接器选项中的“入口点”来完成的。这通常是一个不带参数并返回 void 的函数。

就 Windows 而言,入口点函数是:

  • 安慰: void __cdecl mainCRTStartup( void ) {}
  • 图形用户界面: void __stdcall WinMainCRTStartup( void ) {}
  • 动态链接库: BOOL __stdcall _DllMainCRTStartup(HINSTANCE hinstDLL,DWORD fdwReason,void* lpReserved) {}

在正常的 main/WinMain/DllMain 上使用它们的唯一原因是如果您想使用自己的运行时库(如果您想要更小的文件大小或自定义功能)

有关自定义运行时实现和获取较小 PE 文件的其他技巧,请参阅:

专家 C++/CLI (查看第 279 页)包含本机、混合和纯 CLR 程序集的不同引导场景的非常具体的详细信息。

它依赖于操作系统。在 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”函数,甚至在“main”函数之前:

(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 ()

如果您对与 Windows 和 Win32 API 相关的书籍感兴趣,请尝试

Jeffrey Richter 的“Microsoft Windows 编程应用程序”。

您可以查看以下链接:

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top