解析LNK4098: defaultlib '冲突

这个警告:

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

是Visual Studio中相当常见的警告。我想知道它的确切原因和正确的处理方法(如果有的话)。

这在调试版本中出现,用/MDd编译。该项目链接到窗口Version.dllpdh.dll,它们本身链接到MSVCRT.dll。显然,我没有这些文件的调试版本,无法编译它们。

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

211529 次浏览

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

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

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

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

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

好吧,用正确的方法解决这个问题,找到你正在链接的.obj或.lib文件,该文件是用错误的/M选项编译的。如果你没有线索,那么你可以通过grep .obj/找到它。lib文件"/MT"

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

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

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

检查所有的库,看看它们是否以相同的方式编译。

有关此错误的更多信息,请参见此链接:

warning LNK4098: defaultlib "LIBCD"冲突使用其他lib

每次我想在vc++中创建一个应用程序时,我都会得到这个。

右键单击项目,选择“配置属性| C/ c++ |代码生成”下的属性,选择“多线程调试(/MTd)”进行调试配置。

注意,这不会改变你的发布配置的设置-你需要到相同的位置,并选择“多线程(/MT)”发布。

在我看来,这个链接来自Yochai benkler蒂莫是非常好的和相关的,但读起来很痛苦。我写了一个总结。

Yochai,如果你读过这篇文章,请看看最后的备注。


原文为:警告LNK4098: defaultlib "与其他lib的使用冲突

错误

链接:警告LNK4098: defaultlib "LIBCD"与其他词缀的使用冲突;使用/ NODEFAULTLIB:图书馆

意义

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

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

如何解决

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

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

  • < p >[…搜索你所有的库,确保它们有正确的链接设置

在后者中,就像在最初的帖子中提到的那样,会出现两个常见的问题:

  • 你有一个第三方库,它与你的应用程序有不同的链接。

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

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


注意:我想把Yochai Timmer的链接的摘要包含在他自己的回答中,但由于有些人很难正确地审查编辑,我不得不在一个单独的回答中写下它。对不起

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