解决LNK4098:defaultlib'MSVCRT'与.冲突

sho*_*osh 198 dll linker warnings msvcrt visual-studio

这个警告:

LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts
  with use of other libs; use /NODEFAULTLIB:library
Run Code Online (Sandbox Code Playgroud)

在Visual Studio中是一个相当常见的警告.我想了解它的确切原因以及正确的方法(如果有的话)来处理它.

这出现在一个编译的调试版本中/MDd.该项目与windows之类的东西相关联,Version.dllpdh.dll与之相关MSVCRT.dll.显然,我没有这些的调试版本,无法编译它们.

所以我添加/NODEFAULTLIB:MSVCRT到链接器命令行,它实际上删除了警告.但这实际上做了什么?为什么有必要?

Han*_*ant 256

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

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

查看链接器选项,Project + Properties,Linker,Command Line.请注意这里没有提到这些库.链接器自动确定编译器使用了什么/ M开关,以及哪个.lib应通过#pragma comment指令链接.有点重要的是,如果/ M选项与您链接的.lib之间存在不匹配,则会出现可怕的链接错误并难以诊断运行时错误.

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

/ NODEFAULTLIB告诉链接器忽略从/ MT编译代码生成的#pragma comment指令.这可能有效,尽管其他一些链接器错误并不少见.像errno这样的东西,它是静态CRT版本中的extern int,但是对DLL版本中的函数进行宏编辑.许多其他人喜欢这样.

好吧,正确的方法修复此问题,找到您使用错误的/ M选项编译的链接的.obj或.lib文件.如果你没有任何线索,那么你可以通过点击"/ MT"的.obj/.lib文件来找到它.

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

  • 我刚刚学会了追踪错误的CRT库中的库的技巧是将`/ verbose:lib`添加到其他链接器选项中.它显示了.lib文件加载的顺序,允许您查看不正确的文件被拉入的位置. (58认同)
  • @ buzz3791使用/ verbose而不是/ verbose:lib.显示的信息包括库搜索过程,并列出每个库和对象名称(带完整路径),从库中解析的符号以及引用该符号的对象列表./ verbose可以显示找到导致冲突的坏人所需的所有信息. (4认同)
  • 我发现@obmarg'评论有用,但仍然不确定如何使用详细输出,直到我找到http://msdn.microsoft.com/en-us/library/aa267384(v=vs.60).aspx详细输出只会告诉您链接问题中涉及的所有运行时库.您仍然需要确定哪些链接输入已与冲突的运行时库一起编译. (3认同)
  • 感谢这篇文章,我一直在寻找一个仍在使用/ MDd的.lib,我最终找到了一个!谢谢,+ 1 (2认同)

Yoc*_*mer 44

这意味着其中一个依赖的dll使用不同的运行时库进行编译.

项目 - >属性 - > C/C++ - >代码生成 - >运行时库

浏览所有库,看看它们是以相同的方式编译的.

有关此链接中此错误的更多信息:

警告LNK4098:defaultlib"LIBCD"与使用其他库冲突

  • 对于经验不足的程序员来说,这是最好的答案。 (2认同)

For*_*gic 30

来自Yochai Timmer的 IMO 这个链接非常好,相关但很难阅读.我写了一个总结.

Yochai,如果您读过这篇文章,请参阅最后的说明.


对于原始帖子读取:警告LNK4098:defaultlib"LIBCD"与使用其他库冲突

错误

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

含义

系统的一部分被编译为使用单线程标准(libc)库与调试信息(libcd)静态链接

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

如何解决

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

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

  • [...]浏览所有库并确保它们具有正确的链接设置

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

  • 您有第三方库,其链接与您的应用程序不同.

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

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


注意:我想将Yochai Timmer链接的摘要包含在他自己的答案中,但由于有些人无法正确地审阅编辑,我必须在单独的答案中写出来.抱歉


use*_*736 7

每当我想在VC++中创建应用程序时,我都会得到这个.

右键单击该项目,选择Properties,然后在'Configuration properties |下 C/C++ | 代码生成',为调试配置选择"多线程调试(/ MTd)".

请注意,这不会更改Release配置的设置 - 您需要转到相同位置并为Release选择"Multi-threaded(/ MT)".


rae*_*hee 6

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