此代码编译,但没有任何意外,它在链接时失败(没有找到主要内容):
清单1:
void main();
链接错误:\ mingw \ lib \ libmingw32.a(main.o):main.c :(。text + 0x106)未定义引用_WinMain @ 16'
但是,下面的代码编译并链接正常,并带有警告:
清单2:
void (*main)();
警告:'main'通常是一个函数
问题:
在清单1中,链接器应具有 抱怨失踪的“主要”。为什么 它在寻找_WinMain @ 16?
从中生成的可执行文件 列出2只是崩溃。什么是 原因?
感谢您的时间。
答案 0 :(得分:30)
是的,main
不需要是一个函数。这已在一些混淆程序中被利用,这些程序包含名为main
的数组中的二进制程序代码。
main()的返回类型必须是int
(不是void
)。如果链接器正在寻找WinMain
,它会认为您有一个GUI应用程序。
答案 1 :(得分:6)
在大多数C编译系统中,没有与链接的符号相关联的类型信息。你可以将main声明为例如:
char main[10];
并且链接器会非常高兴。正如您所指出的,程序可能会崩溃,无论您是否巧妙地初始化了数组的内容。
你的第一个例子没有定义main,它只是声明它,因此链接器错误。
第二个示例定义main,但不正确。
答案 2 :(得分:4)
案例1是特定于Windows的 - 当_WinMain
被正确定义时,编译器可能会生成main
符号。
案例2. - 你有一个指针,但是作为静态变量 ,它被初始化为零 ,从而导致崩溃。
答案 3 :(得分:3)
在Windows平台上,如果您没有将程序设置为控制台应用程序,则程序的主要单元是WinMain。 “@ 16”表示它需要16个字节的参数。所以只要你给它一个名为WinMain的函数16个字节的参数,链接器就会很高兴。
如果你想要一个控制台应用程序,这表明你搞砸了。
答案 4 :(得分:2)
您声明了一个名为main的指向函数的指针,并且链接器警告您这不起作用。
_WinMain消息与Windows程序的工作方式有关。在C运行时级别之下,Windows可执行文件具有WinMain。
答案 5 :(得分:1)
尝试将其重新定义为int main(int argc, char *argv[])
您所拥有的是链接器错误。链接器期望找到具有该“签名”的函数 - 没有参数
的情况请参阅http://publications.gbdirect.co.uk/c_book/chapter10/arguments_to_main.html等
答案 6 :(得分:0)
在清单1中,您说“我的代码中的其他地方定义了一个main() - 我保证!”。这就是它编译的原因。但你躺在那里,这就是链接失败的原因。你得到丢失的WinMain16错误的原因是因为标准库(对于Microsoft编译器)包含main()的定义,它调用WinMain()。在Win32程序中,您将定义WinMain(),链接器将使用main()的库版本来调用WinMain()。
在清单2中,您有一个名为main defined的符号,因此编译器和编译器都是链接器很高兴,但启动代码将尝试调用位于“main”位置的函数,并发现那里确实没有函数,并且崩溃。
答案 7 :(得分:0)
1。)在执行main中的代码之前调用(编译器/平台)依赖函数,从而调用行为(在linux / glibc的情况下为_init
)。
2)第二种情况下的代码崩溃是合理的,因为系统无法访问符号main
的内容作为一个实际上是指向任意位置的函数指针的函数。