解决LNK4098:defaultlib'MSVCRT'与发生冲突


216

此警告:

LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts
  with use of other libs; use /NODEFAULTLIB:library

在Visual Studio中是相当普遍的警告。我想了解它的确切原因以及正确的处理方式(如果有的话)。

这出现在使用进行编译的调试版本中/MDd。该项目链接到诸如Windows之类的东西Version.dllpdh.dll它们本身也与之链接MSVCRT.dll。显然,我没有这些的调试版本,也无法编译它们。

因此,我将其添加/NODEFAULTLIB:MSVCRT到链接器命令行中,并确实删除了警告。但是,这实际上是做什么的呢?为何有必要?

Answers:


273

vc \ lib中存在4个版本的CRT链接库:

  • libcmt.lib:用于发布版本(/ MT)的静态CRT链接库
  • libcmtd.lib:用于调试版本(/ MTd)的静态CRT链接库
  • msvcrt.lib:CRT(/ MD)的发行版DLL版本的导入库
  • msvcrtd.lib:用于CRT(/ MDd)的调试DLL版本的导入库

查看链接器选项,“项目+属性”,“链接器”,“命令行”。请注意,此处未提及这些库。链接器自动找出编译器使用了哪个/ M开关,以及应该通过#pragma注释指令链接哪个.lib。一点很重要,如果/ M选项和与之链接的.lib之间不匹配,则会出现可怕的链接错误,并且难以诊断运行时错误。

当链接器被告知同时链接到msvcrt.lib libcmt.lib 时,您将看到引用的错误消息。如果将使用/ MT编译的代码与使用/ MD链接的代码相链接,则会发生这种情况。CRT只能有一个版本。

/ NODEFAULTLIB告诉链接器忽略从/ MT编译代码生成的#pragma注释指令。尽管有很多其他链接器错误并不少见,但这可能会起作用。诸如errno之类的东西,在静态CRT版本中是extern int,但是在DLL版本中被宏化为一个函数。许多其他人都这样。

好吧,以正确的方式解决此问题,找到使用错误的/ M选项编译的.obj或.lib文件。如果您不知道,则可以通过将.obj / .lib文件grep到“ / MT”来找到它

顺便说一句:Windows可执行文件(如version.dll)具有自己的CRT版本以完成工作。它位于c:\ windows \ system32中,您不能可靠地将其用于自己的程序,它的CRT标头在任何地方都不可用。程序使用的CRT DLL具有不同的名称(如msvcrt90.dll)。


2
由于这篇文章,我一直在寻找仍在使用/ MDd的.lib,最终找到了一个!谢谢,+ 1
ceztko 2011年

64
我刚刚学会的一种方法,是查找引入错误的CRT库的库,这是/verbose:lib在其他链接器选项中添加的。这表明,.lib文件在加载,让你看到不正确的一项是在拉顺序
obmarg

1
汉斯,有多危险?如果我们无法修复它(我们从供应商那里获得了编译的库),我们可能会面临什么后果?
伊万·尼基丁

3
我发现@obmarg的注释很有用,但直到我发现msdn.microsoft.com/en-us/library/aa267384(v=vs.60).aspx时,它仍然不确定如何使用详细输出,该命令说详细输出将只告诉您所有涉及链接问题的运行时库。然后,您仍然必须找出冲突的运行时库已编译了哪些链接输入。
buzz3791 2015年

4
@ buzz3791使用/ verbose代替/ verbose:lib。显示的信息包括库搜索过程,并列出每个库和对象名称(具有完整路径),从库中解析的符号以及引用该符号的对象列表。/ verbose可以显示找到导致冲突的坏人所需的所有信息。


32

IMO 此链接尤查蒂莫非常好,但相关痛苦阅读。我写了一个总结。

Yochai,如果您阅读过此内容,请参阅结尾处的注释。


对于原始帖子,请阅读:警告LNK4098:defaultlib“ LIBCD”与其他库的使用冲突

错误

链接:警告LNK4098:defaultlib“ LIBCD”与其他库的使用冲突;使用/ NODEFAULTLIB:library

含义

系统的一部分已编译为使用带有调试信息(libcd)的单线程标准(libc)库,该库是静态链接的

而系统的另一部分被编译为使用没有调试信息的多线程标准库,该库位于DLL中并使用动态链接

怎么解决

  • 忽略警告,毕竟这只是一个警告。但是,您的程序现在包含相同功能的多个实例。

  • 使用链接器选项/ NODEFAULTLIB:lib。这不是一个完整的解决方案,即使您可以让程序以这种方式链接,而您忽略了一个警告标志:该代码已针对不同的环境进行了编译,某些代码可能针对单个线程模型进行了编译,而其他代码则针对多线程的。

  • 拖曳所有库,并确保它们具有正确的链接设置

在后者中,如原始帖子中提到的,可能会出现两个常见问题:

  • 您有一个第三方库,该库以不同的方式链接到您的应用程序。

  • 您的代码中还嵌入了其他指令:通常是MFC。如果系统中的任何模块链接到MFC,则所有模块都必须名义上链接到同一版本的MFC。

对于这些情况,请确保您了解问题并在解决方案中做出决定。


注意:我想将Yochai Timmer链接的摘要包含在他自己的答案中,但是由于某些人难以正确查看编辑内容,因此我不得不将其写在单独的答案中。抱歉


7

每当我想在VC ++中创建应用程序时,都会得到此提示。

右键单击项目,选择“属性”,然后在“配置属性| C / C ++ | 代码生成”中,为调试配置选择“多线程调试(/ MTd)”。

请注意,这不会更改Release配置的设置-您需要转到相同的位置,然后为Release选择“多线程(/ MT)”。


4

右键单击项目,选择“属性”,然后在“配置属性| 链接器| 输入| 忽略特定的库并编写msvcrtd.lib

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.