运行库不匹配和VC ++ - 噢,痛苦!

14
似乎我成年后一直被VC++链接器困扰,因为各种库无法达成一致使用运行时库的版本而抱怨或抗拒。 我从未想掌握这个令人沮丧的主题。 所以我只是试图捣鼓,直到它工作为止。 错误消息从来没有用过。 Microsoft的文档对我也不起作用。
有时它找不到函数-因为名称编码不是预期的? 有时它拒绝混合和匹配。 其他时候它只是说:“LINK:警告LNK4098:defaultlib 'LIBCMTD'与其他库的使用冲突;使用/NODEFAULTLIB:library” /NODEFAULTLIB不起作用,但警告似乎是无害的。 “DEFAULTLIB”到底是什么? 链接器是如何决定的? 我从未见过指定链接器要使用哪个运行时库的方法,只知道如何告诉编译器创建哪个库的函数调用。
有“依赖项检查器”程序可以检查目标文件以查看它们所依赖的DLL。 我刚刚在尝试构建的项目上运行了一个,情况很糟糕。 系统.lib和.dll会希望使用不同的运行时版本。 例如,COMCTL32.DLL需要MSVCRT.DLL,但我正在链接MSVCRTD.DLL。 我正在搜索是否有COMCTL32D.DLL,就在我打字的时候。
所以我想要的是如何解决这些问题的教程。 你做什么,怎么做?
这是我知道的。 如果有任何错误,请纠正我。
1. 参数是Debug / Release,Multi-threaded / Single-threaded和static / DLL。 只涵盖八个可能组合中的六个。 没有单线程DLL,无论是Debug还是Release。
  • 这些设置只影响链接到哪个运行库(以及与之链接的调用约定)。例如,如果您正在构建一个DLL,不一定要使用基于DLL的运行时,而构建Debug版本程序时也不必使用Debug版本的运行时,尽管在单步跟踪系统调用时似乎会有所帮助。

  • 奖励问题:任何人或任何公司如何创造出这样的混乱?

    答:可能是因为历史原因、技术选择、需求变更等多种因素导致了系统的复杂性和混乱。
    1个回答

    3
    您的第一点和第二点看起来对我来说是正确的。还需要注意的是,使用调试CRT进行链接还可以访问诸如增强堆检查、已检查迭代器和其他各种健全性检查等功能。但您不能将调试CRT与应用程序一起重新分发--您必须仅使用发布版本进行发行。这不仅是VC许可证要求的,而且您可能也不想发送调试二进制文件。
    不存在名为COMCTL32D.DLL的东西。作为Windows的一部分的DLL必须加载它们在Windows构建时链接的CRT -- 这包括作为MSVCRT.DLL的操作系统。此Windows CRT与加载组成您的程序的模块的Visual C++ CRT完全独立(MSVCRT.DLL是随Windows一起提供的。VC CRT将包括版本号,例如MSVCRT80.DLL)。只有构成您的程序的EXE和DLL文件会受到调试/发布多线程/单线程设置的影响。
    在我看来,最佳实践是为CRT选择一个设置,并为您发行的每个二进制文件标准化该设置。我个人会使用多线程DLL运行时。这是因为Microsoft可以(并确实)向CRT发布安全更新和错误修复,这些更新可以通过Windows Update推出。

    1
    太好了!我想我明白了,但是当我不可避免地发现我不明白时,保留提问的权利。顺便说一下,在我现在正在工作的项目中,我已经成功将Release和Debug都链接并运行了,但是Release版本告诉我:“LINK:警告LNK4098:defaultlib 'LIBCMT'与其他库的使用冲突;使用/NODEFAULTLIB:library。”这让我感到困惑,因为我已经选择了多线程DLL用于代码生成(/MD)。Debug版本链接干净。我正在链接wxWidgets、lcms、opencv以及其他那些引入的东西。继续前进吧! - Jive Dadson
    2
    我已经发现如何在VC++ IDE中有效地使用“/NODEFAULTLIB:libray”。打开“属性”,然后进入“链接器/输入”页面。将有问题的DEFAULTLIB名称放入文本框“忽略特定库”。 - Jive Dadson

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接