你的位置:pcMing工作室 >> 资讯 >> 编程开发 >> C++编程 >> 详细内容 在线投稿

解决VC+++ fatal error LNK1169: one or more multiply错误

排行榜 收藏 打印 发给朋友 举报 来源: 互联网   发布者:未知
热度3050票  浏览1604次 【共0条评论】【我要评论 时间:2010年3月28日 16:24

HmXC&xx"{0

2{G$] j`)d e!O0
r`$Ihy l'Q0
9X0OxQU8S.A0上文描述了虽然各目标模块指定了不同版本的缺省标准库但仍然链接成功的例子,接下来你将目睹因为这种不严谨而导致的悲惨失败。
D_:iB:R CHz(|e0pcMing工作室.hC ^)X"^ l@;EZ
修改mylib.c成这个样子:
u0oB t2^1`3fV0
`$LHR8U0#i nclude
Z"_3c%B ak$`#a%z(k.P0
nM4_9g {C.IF0void foo()
k%k!Z|-SS0{
fO{ Ev;h"Xx0// just a test , don"t care memory leak
zn`CqP d0_malloc_dbg( 1, _NORMAL_BLOCK, __FILE__, __LINE__ );
-[)cg'Ukip3xt0}
2nd]qK6{5kN;n0pcMing工作室%c5JX L&h
其中_malloc_dbg不是ANSI C的标准库函数,它是VC标准库提供的malloc的调试版,与相关函数配套能帮助开发者抓各种内存错误。使用它一定要定义_DEBUG宏,否则预处理器会把它自动转为malloc。继续用
| OP-`:s8q N!R8m0pcMing工作室4\8e[ U(qiQFc
cl /c /MLd mylib.c
smJ*@-z0oDZ0lib /OUT:my.lib mylib.obj
~jD~APm0pcMing工作室/A1p+f-{9l5t
编译打包。当再次用
2].jeI w\3v b]I0F Yc0
(~"FwY![X0link main.obj my.lib
T kJRG+wk'I-Wp9T0
KEl4I\$y`g w0进行链接时,我们看到了什么?天哪,一堆的LNK2005加上个贵为"fatal error"的LNK1169垫底,当然还少不了那个LNK4098。链接器是不是疯了?不,你冤枉可怜的链接器了,我拍胸脯保证它可是一直在尽心尽责地照章办事。pcMing工作室i~!E+F*s4B(y m
pcMing工作室 q1q,r/R'e aU3F}8I7C7L
一开始E、U、D为空,链接器扫描main.obj,把它加入E,把foo加入U,把main加入D,把libc.lib加入到当前输入文件列表的末尾。接着扫描my.lib,foo从U转移到D,_malloc_dbg加入到U,libcd.lib加到当前输入文件列表的尾部。然后扫描 libc.lib,这时会发现libc.lib里任何一个目标模块都没有定义_malloc_dbg(它只在调试版的标准库中存在),所以不会有任何一个模块因为_malloc_dbg而加入E,但是每个程序都要用到的初始化模块(如crt0.obj等)及它们所引用的模块(比如malloc.obj、 free.obj等)还是会自动加入到E中,同时U和D被更新以反应这个变化。当链接器处理完libc.lib时,U只剩_malloc_dbg这一个符号。最后处理libcd.lib,发现dbgheap.obj定义了_malloc_dbg,于是dbgheap.obj加入到E,它里头的未解析符号加入U,它定义的所有其它符号也加入D,这时灾难便来了。之前malloc等符号已经在D中(随着libc.lib里的malloc.obj加入E而加入的),而dbgheap.obj又定义了包括malloc在内的许多同名符号,这引发了重定义冲突,链接器只好中断工作并报告错误。
0V6K]e%TJ @j0pcMing工作室EK8lJPTK
现在我们该知道,链接器完全没有责任,责任在我们自己的身上。是我们粗心地把缺省标准库版本不一致的目标文件(main.obj)与程序库 (my.lib)链接起来,导致了大灾难。解决办法很简单,要么用/MLd选项来重编译main.c;要么用/ML选项重编译mylib.c。pcMing工作室R6F$S)k.M

pK%t*e.uF:Y0在上述例子中,我们拥有库my.lib的源代码(mylib.c),所以可以用不同的选项重新编译这些源代码并再次打包。可如果使用的是第三方的库,它并没有提供源代码,那么我们就只有改变自己程序的编译选项来适应这些库了。但是如何知道库中目标模块指定的默认库呢?其实VC提供的一个小工具便可以完成任务,这就是dumpbin.exe。运行下面这个命令pcMing工作室cdo,}*J8wN2T
pcMing工作室'x wy%i$pJ A gS
dumpbin /DIRECTIVES my.lib
%I} O$c{.LA0
gim+P/qL4@+Y+[!\V0然后在输出中找那些"Linker Directives"引导的信息,你一定会发现每一处这样的信息都会包含若干个类似"-defaultlib:XXXX"这样的字符串,其中XXXX便代表目标模块指定的缺省库名。
x'KRK(~6yL F0
YR5Zm h0知道了第三方库指定的默认标准库,再用合适的选项编译我们的应用程序,就可以避免LNK2005和LNK1169链接错误。喜欢IDE的朋友,你一样可以到 "Project属性" -> "C/C++" -> "代码生成(code generation)" -> "运行时库(run-time library)" 项下设置应用程序的默认标准库版本,这与命令行选项的效果是一样的。pcMing工作室*g/dacR ^j

%AMdRw7D'i[ i0终极解决办法:pcMing工作室 `$ck8L v9yl
pcMing工作室/N%P:[Z wc
在 Project/Setting/Link/General中的 Project Options: 加入 /FORCE:MULTIPLE即可

/M}2DaB\? ezt0

Ow(MO0Z0 pcMing工作室0`&a#p6H(O{[(n;s%{)m

{4nlE0L&t!eM.v0属于编译联接的常见问题之一,原因是在不同的源文件重复定义变量。  pcMing工作室"Meg~^m-Y
  比如project1有2个c或cpp文件,假设为a.c,b.c如果  
XS&xE9Ng\(qRj0  1,定义了相同名字的变量;  
'k&K:X({ _`f0  2,包含了同样的头文件(其中定义了非局部变量);  
a:T+a`fCS0  这样在编译生成的a.obj,b.obj文件中都会为为这个同一变量  pcMing工作室'U8K;f~B?
  分配空间,linker会作名称检查,如果出现相同名字就会出现  
C!UE*e5?#Ob0  fatal   error   LNK1169:   one   or   more   multiply   defined   symbols   found  
l:g3n;GICa Tqe)]0  解决方法,对于第一种情况,用external关键字屏蔽其它重复定义即可;  pcMing工作室~rK:?5x
  实际上情况2更隐蔽常见,只能避免定义非局部变量pcMing工作室$gG KeA xG2j5W

顶:184 踩:158
对本文中的事件或人物打分:
当前平均分:-0.33 (939次打分)
对本篇资讯内容的质量打分:
当前平均分:-0.32 (916次打分)
【已经有853人表态】
118票
感动
118票
路过
91票
高兴
85票
难过
123票
搞笑
92票
愤怒
106票
无聊
120票
同情
上一篇 下一篇
发表评论
换一张

网友评论仅供网友表达个人看法,并不表明本网同意其观点或证实其描述。

查看全部回复【已有0位网友发表了看法】

网络资源