问题描述
似乎在我成年后的所有生活中,我都被 VC++ 链接器的抱怨或犹豫所折磨,因为各种库在使用哪个版本的 Runtime 库上存在分歧.我从来没有心情去掌握那个令人沮丧的主题.所以我只是试着把它弄乱,直到它起作用为止.错误消息从来没有用.微软关于这个主题的文档也不是 - 至少对我来说不是.
It seems that all my adult life I've been tormented by the VC++ linker complaining or balking because various libraries do not agree on which version of the Runtime library to use. I'm never in the mood to master that dismal subject. So I just try to mess with it until it works. The error messages are never useful. Neither is the Microsoft documentation on the subject - not to me at least.
有时它找不到函数 - 因为名称修改不是预期的?有时它拒绝混搭.其他时候它只是说,"LINK : warning LNK4098: defaultlib 'LIBCMTD' 与其他库的使用冲突;使用/NODEFAULTLIB:library" 使用/NODEFAULTLIB 不起作用,但警告似乎是良性的.DEFAULTLIB"到底是什么?链接器如何决定?我从未见过向链接器指定要使用哪个运行时库的方法,只有如何告诉编译器为哪个库创建函数调用.
Sometimes it does not find functions - because the name-mangling is not what was expected? Sometimes it refuses to mix-and-match. Other times it just says, "LINK : warning LNK4098: defaultlib 'LIBCMTD' conflicts with use of other libs; use /NODEFAULTLIB:library" Using /NODEFAULTLIB does not work, but the warning seems to be benign. What the heck is "DEFAULTLIB" anyway? How does the linker decide? I've never seen a way to specify to the linker which runtime library to use, only how to tell the compiler which library to create function calls for.
有dependency walker"程序可以检查目标文件以查看它们所依赖的DLL.我刚刚在我正在尝试构建的项目上运行了一个,这真是一团糟.有系统 .libs 和 .dll 需要冲突的运行时版本.例如,COMCTL32.DLL 需要 MSVCRT.DLL,但我正在链接 MSVCRTD.DLL.我正在搜索是否有 COMCTL32D.DLL,即使在我输入时也是如此.
There are "dependency walker" programs that can inspect object files to see what DLL's they depend on. I just ran one on a project I'm trying to build, and it's a real mess. There are system .libs and .dll's that want conflicting runtime versions. For example, COMCTL32.DLL wants MSVCRT.DLL, but I am linking with MSVCRTD.DLL. I am searching to see if there's a COMCTL32D.DLL, even as I type.
所以我想我要的是关于如何解决这些问题的教程.你是做什么的,你是怎么做的?
这就是我认为我知道的.如有不对之处请指正.
Here's what I think I know. Please correct me if any of this is wrong.
参数是Debug/Release、Multi-threaded/Single-threaded和static/DLL.仅涵盖了八种可能组合中的六种.没有单线程 DLL,无论是 Debug 还是 Release.
The parameters are Debug/Release, Multi-threaded/Single-threaded, and static/DLL. Only six of the eight possible combinations are covered. There is no single-threaded DLL, either Debug or Release.
这些设置只影响链接到哪个运行时库(以及与之链接的调用约定).例如,如果您正在构建 DLL,您不必使用基于 DLL 的运行时,也不必在构建程序的调试版本时使用调试版本的运行时,尽管它似乎有助于单-跳过系统调用.
The settings only affect which runtime library gets linked in (and the calling convention to link with it). You do not, for example, have to use a DLL-based runtime if you are building a DLL, nor do you have to use a Debug version of runtime when building the Debug version of a program, although it seems to help when single-stepping past system calls.
额外的问题:任何人或任何公司怎么能制造出如此混乱的局面?
Bonus question: How could anyone or any company create such a mess?
推荐答案
你的观点 (1) 和 (2) 在我看来是正确的.与 (2) 相关的另一件事是,调试 CRT 中的链接还使您可以访问诸如增强的堆检查、已检查的迭代器和其他各种健全性检查之类的内容.但是,您不能将调试 CRT 与应用程序一起重新分发——您必须仅使用发布版本进行发布.它不仅是 VC 许可证所要求的,而且您可能无论如何都不想发布调试二进制文件.
Your points (1) and (2) look correct to me. Another thing to note with (2) is that linking in the debug CRT also gives you access to things like enhanced heap checking, checked iterators, and other assorted sanity checks. You cannot redistribute the debug CRT with your application, however -- you must ship using the release build only. Not only is it required by the VC license, but you probably don't want to be shipping debug binaries anyway.
没有COMCTL32D.DLL
这样的东西.作为 Windows 一部分的 DLL 必须加载它们在构建 Windows 时链接到的 CRT——这作为 MSVCRT.DLL
包含在操作系统中.此 Windows CRT 完全独立于由组成程序的模块加载的 Visual C++ CRT(MSVCRT.DLL
是 Windows 附带的那个.VC CRT 将包含一个版本号,用于示例 MSVCRT80.DLL
).只有组成您程序的 EXE 和 DLL 文件会受到调试/发布多线程/单线程设置的影响.
There is no such thing as COMCTL32D.DLL
. DLLs that are part of Windows must load the CRT that they were linked against when Windows was built -- this is included with the OS as MSVCRT.DLL
. This Windows CRT is completely independent from the Visual C++ CRT that is loaded by the modules that comprise your program (MSVCRT.DLL
is the one that ships with Windows. The VC CRT will include a version number, for example MSVCRT80.DLL
). Only the EXE and DLL files that make up your program are affected by the debug/release multithreaded/single-threaded settings.
IMO 的最佳做法是为您的 CRT 选择一个设置,并针对您发送的每个二进制文件对其进行标准化.我个人会使用多线程 DLL 运行时.这是因为 Microsoft 可以(并且确实)向 CRT 发布安全更新和错误修复,这些更新和错误修复可以通过 Windows 更新推出.
The best practice here IMO is to pick a setting for your CRT and standardize upon it for every binary that you ship. I'd personally use the multithreaded DLL runtime. This is because Microsoft can (and does) issue security updates and bug fixes to the CRT that can be pushed out via Windows Update.
这篇关于运行时库与 VC++ 不匹配 - 哦,痛苦!的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!