· [Java论坛][安全论坛][数据库论坛][操作系统论坛]
· [访谈] 网银安全系列访谈之:惊心动魄网银故事
· [热点专题] 网银安全系列 3G上网卡巡礼
· [订阅IT技术周刊][IT资源下载专区][病毒求助专区]
· [热点] 跨站脚本十二问 四步防范Conficker
· [热点] Windows 7 RC版公开下载 憾缺中文版

解决出现的LNK2005“符号已定义”错误 (2)

发布时间:2006.03.13 05:31     来源:Blog    作者:soloist

由上可知多个目标文件不能重复定义同名的函数与初始化了的全局变量,否则必然导致LNK2005和LNK1169两种链接错误。可是,有的时候我们并没有在自己的程序中发现这样的重定义现象,却也遇到了此种链接错误,这又是何解?嗯,问题稍微有点儿复杂,容我慢慢道来。

    众所周知,ANSI C/C++ 定义了相当多的标准函数,而它们又分布在许多不同的目标文件中,如果直接以目标文件的形式提供给程序员使用的话,就需要他们确切地知道哪个函数存在于哪个目标文件中,并且在链接时显式地指定目标文件名才能成功地生成可执行文件,显然这是一个巨大的负担。所以C语言提供了一种将多个目标文件打包成一个文件的机制,这就是静态程序库(static library)。开发者在链接时只需指定程序库的文件名,链接器就会自动到程序库中寻找那些应用程序确实用到的目标模块,并把(且只把)它们从库中拷贝出来参与构建可执行文件。几乎所有的C/C++开发系统都会把标准函数打包成标准库提供给开发者使用(有不这么做的吗?)。

    程序库为开发者带来了方便,但同时也是某些混乱的根源。我们来看看链接器是如何解析(resolve)对程序库的引用的。
    
在符号解析(symbol resolution)阶段,链接器按照所有目标文件和库文件出现在命令行中的顺序从左至右依次扫描它们,在此期间它要维护若干个集合:(1)集合E是将被合并到一起组成可执行文件的所有目标文件集合;(2)集合U是未解析符号(unresolved symbols,比如已经被引用但是还未被定义的符号)的集合;(3)集合D是所有之前已被加入到E的目标文件定义的符号集合。一开始,E、U、D都是空的。

(1): 对命令行中的每一个输入文件f,链接器确定它是目标文件还是库文件,如果它是目标文件,就把f加入到E,并把f中未解析的符号和已定义的符号分别加入到U、D集合中,然后处理下一个输入文件。

(2): 如果f是一个库文件,链接器会尝试把U中的所有未解析符号与f中各目标模块定义的符号进行匹配。如果某个目标模块m定义了一个U中的未解析符号,那么就把m加入到E中,并把m中未解析的符号和已定义的符号分别加入到U、D集合中。不断地对f中的所有目标模块重复这个过程直至到达一个不动点(fixed point),此时U和D不再变化。而那些未加入到E中的f里的目标模块就被简单地丢弃,链接器继续处理下一输入文件。

<<上一页 1 2 3 4 5 6 下一页>>


[ 发表评论 ] 字体[  ] [ 打印 ] [ 进入博客 ] [ 进入论坛 ]  [ 推荐给朋友 ]
  相关文章
· 取长补短:Simulink与VC++6.0接口比较 (03-10) · C++箴言:如何访问模板化基类中的名字 (03-09)
· 也玩视觉效果:VC++编程实现仿真火焰 (03-09) · 体验C++中接口与实现分离的技术 (03-09)
· Stan Lippman:C++/CLI全景体验 (03-08) · 用VC++制作播放AVI视频流的动画按钮 (03-07)
· Visual C++ 6.0编程实现打印功能 (03-02) · VC++串口编程之短信应用开发 (02-24)
· 学习C++编程语言的最大难度是什么 (02-24) · Linux下C++程序的异常处理技巧 (02-22)
  客户需求反馈表
* 姓  名:
更多资料  了解方案  认识厂商
* 单位名称:
* 联系电话:
* 电子邮件:
资讯 通信 IT产品 IT技术 信息化
2009第七届中国电脑商年会直播
·创业投资系列访谈:产业..
·特别策划:视频网站系列..
·专题:网游虚拟货币新规..
专题:6月上市手机新品回顾及7月新机展望
·2009年中国电信业信息化..
·专题:把iPhone 3GS“解..
·WAPI重启国际标准进程 ..
专题:09年中盘点-联想春季打印机新品回顾
·InfoComm 2009 视听与集..
·网游背后的故事 网游服..
·[专题]联想ThinkPad T40..
BizSpark:微软为技术创业企业点燃火花
·社区活动:我的IT求知生..
·访谈:内网安全2009系列..
·安全访谈:网银安全之Sa..