设为首页 加入收藏

TOP

学习windows编程(6)改换entry,link错误的简单分析(一)
2014-11-23 22:13:16 来源: 作者: 【 】 浏览:4
Tags:学习 windows 编程 改换 entry link 错误 简单 分析

从零开始,学习windows编程(6)--改换entry,link错误的简单分析
还是那个hello.c程序,我们将其小修改一下,来开始今天的话题。


1 #include
2
3 int myentry()
4 {
5 printf("hello world");
6 return 0;
7 }可以看到,我将原来main的位置换成了myentry,这会有什么结果发生呢?

D: est>cl /c hello.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

hello.c

OK,没有问题,生成了hello.obj。

D: est>link hello.obj
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

LIBC.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
hello.exe : fatal error LNK1120: 1 unresolved externals

link过程出现了问题,报了一个LINK2001错误。这个错误在MSDN上是这么说的:

unresolved external symbol "symbol"

Code references something (such as a function, variable, or label) that the linker cant find in the libraries and object files.

Possible causes

What the code asks for doesnt exist (the symbol is spelled incorrectly or uses the wrong case, for example).
The code asks for the wrong thing (you are using mixed versions of the libraries, some from one version of the product, others from another version).
This error message is followed by fatal error LNK1120.

具体原因,其实结合前面几篇的知识,就可以很容易的推理出来。如果大家有兴趣,可以试着先推理一下,再看下面的分析过程,这样理解更深刻一些。

对于LINK错误,应该算是C/C++特有的,而且比较麻烦,难以理解和解决的一类错误。C语言还好一些,到了C++中,LINK错误常常会带一些“乱码”符号,就更让初次接触到的童鞋们摸不到头脑了。正好借这一个小例子,来看一下思路。

首先,我们使用cl从hello.c生成了hello.obj文件,由于没有加上/Zl选项,所以生成的hello.obj文件还是带有两个defaultlib的,一个为libc.lib,还有一个oldnames.lib。这样,在LINK的时候,会将hello.obj与libc.lib进行链接,而libc.lib是很多obj合在一起形成的,里面有crt0.c生成的名为crt0.obj文件。回想我们上次看到的crt0.c的源码文件,里面函数为mainCRTStartup,在mainCRTStartup函数中调用到main函数了,main函数这个external symbol没有找到(其他函数如_heap_init。。。看来都是找到了),所以报出来一个LNK2001错误,告诉用户,main这个symbol没有找到,您把它忘哪儿啦。

相关扩展

link时使用/entry选项选定入口

D: est>cl /c hello.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

hello.c

D: est>link /entry:myentry hello.obj
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

LIBC.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
hello.exe : fatal error LNK1120: 1 unresolved externals

其他不变,在link的时候加上/entry选项,结果还是和原来一样。因此,可以确定,link过程需要将所有的符号找到其所,而不像编译过程可以“打马虎眼”,即使是有一些external的也可以不理。另外,不管这个函数有没有“使用”到,都必须被link程序找到。这里的“使用”意思为执行过程中,执行到它。可以再看一个例子:


1 #include 2 3 int myentry() 4 { 5 printf("hello world"); 6 return 0; 7 } 8 9 int main()10 {11 myentry();12 }13 14 int test()15 {16 nofunc();17 return 0;18 }从上面的代码可以看到,在默认编译链接的情况下,test函数是没有被调用到的,而其中的nofunc函数是没有定义的。我们来对其做一下编译链接。

D: est>cl /c hello.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

hello.c

D: est>link hello.obj
Microsoft (R) Incremental Linker Version 6.00.8447
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

hello.obj : error LNK2001: unresolved external symbol _nofunc
hello.exe : fatal error LNK1120: 1 unresolved externals

可以看到,link的时候,找不到nofunc这个symbol,从而报错。

这也是C/C++的一个比其他语言麻烦的地方,有编译时、链接时和运行时的划分,这样子清晰了,但是概念也多了,如果再加上隐藏了一些东西的实现和原理,理解起来就更不容易了。

使用/Zl选项

如果对myentry代码使用/Zl选项。

D: est>cl /c /Zl hello.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Micros

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇学习windows编程(7)不使用CRT库.. 下一篇求单向链表倒序第m个元素

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: