【问题标题】:Trying to understand the main function with GCC and Windows试图理解 GCC 和 Windows 的主要功能
【发布时间】:2012-10-26 04:43:42
【问题描述】:

他们说 main() 是一个与任何其他函数一样的函数,但被“标记”为二进制文件中的入口点,操作系统可能会找到的入口点 (Don '不知道如何)并从那里启动程序。因此,我正在尝试了解有关此功能的更多信息。我做了什么?我创建了一个简单的 .C 文件,其中包含以下代码:

int main(int argc, char **argv) {
     return (0);
}

我保存了文件,安装了 GCC 编译器(在 Windows,MingW 环境中)并创建了一个批处理文件,如下所示:

gcc -c test.c -nostartfiles -nodefaultlibs -nostdlib -nostdinc -o test.o
gcc -o test.exe -nostartfiles -nodefaultlibs -nostdlib -nostdinc -s -O2 test.o
@%comspec%

我这样做是为了获得一个非常简单的编译器和链接器,没有库,没有头文件,只有编译器。因此,编译顺利,但链接停止并出现此错误:

test.c:(.text+0xa): undefined reference to '___main'
collect2.exe: error: Id returned 1 exit status

我认为主函数是由链接器导出的,但我相信您不需要任何包含有关它的附加信息的库。但它看起来确实如此。就我而言,我认为它必须是标准的 GCC 库,所以我下载了它的源代码并打开了这个文件:libgcc2.c 现在,我不知道这是否是构建主函数以由 GCC 链接的文件。其实我不明白 GCC 是怎么使用 main 函数的。为什么链接器需要 gcc 标准库? 想知道 main 是怎么回事?我希望这让我的问题变得非常具体和清晰。谢谢!

【问题讨论】:

  • 你能从你的windows运行nm test.o吗?它会告诉你 test.o 中包含的符号
  • 是的,有一个 '___main' 和 '_main' 符号(这很奇怪)

标签: c windows gcc export main


【解决方案1】:

当 gcc 将所有对象文件 (test.o) 和库放在一起形成二进制文件时,它还会预先添加一个小对象(通常是 crt0.o 或 crt1.o),它负责调用您的 main()。当你在命令行中添加 -v 时,你可以看到 gcc 正在做什么:

$ gcc -v -o test.exe test.o

crt0/crt1 进行一些设置,然后调用 main。但是链接器最终负责根据操作系统构建可执行文件。使用-v,您还可以看到目标系统的选项。就我而言,它适用于 64 位 Linux:-m elf_x86_64。对于您的系统,这将类似于 -m windows-m mingw

【讨论】:

  • 谢谢,这真的很有帮助。
  • 好的。因此 crt0.o 包含附加到可执行文件的平台相关信息,以便 Windows 或任何其他操作系统。可以根据自己的规则找到入口点,不是吗?
【解决方案2】:

发生错误是因为您使用了这两个选项:-nodefaultlibs -nostdlib

这些告诉 GCC 它不应该将您的代码链接到 libc.a/c.lib,其中包含真正调用 main() 的代码。简而言之,每个操作系统都略有不同,其中大多数都不关心 C 和 main()。每个进程都有自己特殊的启动进程的方式,并且大多数都与 C API 不兼容。

所以 C 开发人员的解决方案是将“胶水代码”放入 C 标准库 libc.a,其中包含操作系统期望的接口,创建标准 C 环境(设置内存分配结构,所以 malloc()将映射操作系统的内存管理功能,设置stdio等)并最终调用main()

对于 C 开发人员来说,这意味着他们的操作系统(以及编译器二进制文件)获得了 libc.a,并且他们不需要关心设置的工作原理。

另一个混淆来源是参考的名称。在大多数系统上,main() 的符号名称是_main(即一个下划线),而__main 是由设置代码调用的内部函数的名称,最终调用真正的main()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-01
    • 1970-01-01
    • 2019-01-11
    • 2012-09-13
    • 1970-01-01
    • 2018-12-17
    • 2022-01-15
    相关资源
    最近更新 更多