【问题标题】:Resolving LNK4098: defaultlib 'MSVCRT' conflicts with解决 LNK4098:defaultlib 'MSVCRT' 与
【发布时间】:2011-03-01 17:48:19
【问题描述】:

此警告:

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,它实际上确实删除了警告。但这实际上有什么作用?为什么有必要?

【问题讨论】:

    标签: visual-studio dll linker warnings msvcrt


    【解决方案1】:

    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 版本中是一个函数的宏。许多其他人都喜欢这样。

    好吧,用正确的方法解决这个问题,找到你要链接的 .obj 或 .lib 文件,它是用错误的 /M 选项编译的。如果您不知道,那么您可以通过 grepping .obj/.lib 文件来查找“/MT”

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

    【讨论】:

    • 感谢这篇文章,我一直在寻找仍在使用 /MDd 的 .lib 文件,最终找到了!谢谢,+1
    • 我刚刚学会的一个技巧是在附加的链接器选项中添加/verbose:lib 来追踪拉入错误 CRT 库的库。它显示了 .lib 文件的加载顺序,让您可以看到不正确的文件被拉入的位置。
    • 汉斯,有多危险?如果我们无法修复它(我们从供应商那里获得编译好的库),我们可能会面临什么后果?
    • 我发现@obmarg' 评论很有用,但我仍然不确定如何使用详细输出,直到我找到msdn.microsoft.com/en-us/library/aa267384(v=vs.60).aspx,它说详细输出只会告诉您链接中涉及的所有运行时库问题。您仍然需要确定哪个链接输入已使用冲突的运行时库进行编译。
    • @buzz3791 使用 /verbose 而不是 /verbose:lib。显示的信息包括库搜索过程并列出每个库和对象名称(带有完整路径)、从库中解析的符号以及引用该符号的对象列表。 /verbose 可以显示您找到导致冲突的坏人所需的所有信息。
    【解决方案2】:

    这意味着其中一个依赖的dll是用不同的run-time library编译的。

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

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

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

    warning LNK4098: defaultlib "LIBCD" conflicts with use of other libs

    【讨论】:

    • 这就是错误的原因!感谢您的提示。
    • 这是经验不足的程序员的最佳答案。
    【解决方案3】:

    来自Yochai Timmer 的IMO this link 非常好且相关,但读起来很痛苦。我写了一个总结。

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


    原帖请阅读:warning LNK4098: defaultlib "LIBCD" conflicts with use of other libs

    错误

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

    意义

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

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

    如何解决

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

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

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

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

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

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

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


    注意:我想将 Yochai Timmer 链接的摘要包含在他自己的答案中,但由于有些人无法正确审查编辑,我不得不将其写在单独的答案中。对不起

    【讨论】:

      【解决方案4】:

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

      右键单击项目,选择“属性”,然后在“配置属性 | C/C++ | Code Generation',Debug配置选择“Multi-threaded Debug (/MTd)”。

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 2022-01-06
          • 1970-01-01
          • 1970-01-01
          • 2016-06-15
          • 1970-01-01
          • 1970-01-01
          • 2011-03-13
          • 1970-01-01
          相关资源
          最近更新 更多