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

发布于 2024-08-23 01:24:29 字数 917 浏览 5 评论 0原文

似乎在我的整个成年生活中,我一直被 VC++ 链接器抱怨或犹豫所折磨,因为各种库在使用哪个版本的运行库上没有达成一致。我从来没有心情去掌握这个令人沮丧的主题。所以我只是尝试搞乱它,直到它起作用为止。错误消息永远没有用。微软关于这个主题的文档也不是——至少对我来说不是。

有时它找不到函数 - 因为名称修改不是预期的?有时它拒绝混合搭配。其他时候它只是说,“LINK:警告 LNK4098:defaultlib 'LIBCMTD' 与其他库的使用冲突;使用 /NODEFAULTLIB:library” 使用 /NODEFAULTLIB 不起作用,但警告似乎是良性的。 “DEFAULTLIB”到底是什么?链接器如何决定?我从未见过一种方法来指定链接器使用哪个运行时库,只知道如何告诉编译器创建函数调用的库。

有一些“dependency walker”程序可以检查目标文件以查看它们所依赖的 DLL。我刚刚在我正在尝试构建的项目上运行了一个,这真是一团糟。有些系统 .lib 和 .dll 需要冲突的运行时版本。例如,COMCTL32.DLL 想要 MSVCRT.DLL,但我正在与 MSVCRTD.DLL 链接。我正在搜索是否有 COMCTL32D.DLL,甚至在我键入时也是如此。

所以我想我想要的是一个关于如何解决这些问题的教程。你是做什么的,怎么做?

这是我认为我所知道的。如果其中有任何错误,请纠正我。

  1. 参数为调试/发布、多线程/单线程、静态/DLL。仅涵盖八种可能组合中的六种。没有单线程DLL,无论是Debug还是Release。

  2. 这些设置仅影响链接的运行时库(以及与其链接的调用约定)。例如,如果您正在构建 DLL,则不必使用基于 DLL 的运行时;在构建程序的调试版本时,也不必使用运行时的调试版本,尽管它在单一运行时似乎有所帮助。跳过系统调用。

额外问题:任何人或任何公司怎么能造成如此混乱?

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.

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.

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.

So I guess what I'm asking for is a tutorial on how to sort those things out. What do you do, and how do you do it?

Here's what I think I know. Please correct me if any of this is wrong.

  1. 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.

  2. 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

倾城°AllureLove 2024-08-30 01:24:29

我认为你的观点(1)和(2)是正确的。 (2) 中需要注意的另一件事是,调试 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 文件才会受到调试/发布多线程/单线程设置的影响。

IMO 的最佳实践是为您的 CRT 选择一个设置,并针对您发送的每个二进制文件对其进行标准化。我个人会使用多线程 DLL 运行时。这是因为 Microsoft 可以(并且确实)向 CRT 发布可通过 Windows Update 推出的安全更新和错误修复。

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.

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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文