【问题标题】:Why is "Use MFC in a Static Library" setting not followed when building a DLL with VS 2008?为什么在使用 VS 2008 构建 DLL 时不遵循“在静态库中使用 MFC”设置?
【发布时间】:2026-01-05 23:45:02
【问题描述】:

我的目标是创建一个 MFC/C++ DLL,它除了基本的 Win32 DLL 之外没有任何依赖项。所以我在项目属性中选择了"Use MFC in a Static Library"设置->General->Use of MFC:

但是当我构建这个 DLL 并使用 Dependency Walker 检查结果时,我得到了这个:

显示对以下 MFC Dll 的依赖关系:

MFC90U.DLL
MSVCR90.DLL
MSVCP90.DLL

那么我在这里做错了什么?

PS。我正在使用 Visual Studio 2008

【问题讨论】:

  • 是否启用了增量链接?重建所有帮助吗?
  • MSVCR90.DLLMSVCP90.DLL 不是 MFC 二进制文件。
  • @IInspectable:嗯,老实说,我从来没有考虑过。但是,如果您将项目构建为使用“MFC 作为共享 DLL”,则这些文件将包含在内。默认情况下,它们也不包含在 Windows XP 安装中(甚至可能是 Vista),因此必须通过 MSI(和“DLL-Hell”)分发。
  • 正确,运行时支持库是 VS 2008 中编译器的一部分,而不是操作系统。这只在 Windows 10 中发生了变化,Universal CRT 是操作系统的一部分。

标签: c++ windows visual-c++ visual-studio-2008 mfc


【解决方案1】:

我想我明白了。让我感到困惑的是C++ -> Code Generation -> Runtime Library 中的项目设置。改成Multi-threaded DLL (/MD),然后在stdafx.h文件中添加了以下内容:

#define _AFXDLL

因此,要使其静态链接到 MFC 库,我必须将第一个设置更改为 Multi-threaded (/MT) 并注释掉第二个设置。

【讨论】:

  • 希望您现在了解Potential Errors Passing CRT Objects Across DLL Boundaries 如何适用于您的情况。通过静态链接 CRT,您不能再安全地跨 DLL 边界传递 CRT 对象(例如内存)。
  • @IInspectable:希望吧。
  • 我会远离 CRT 对象以跨越 DLL 边界。我使用原始类型、内存缓冲区指针或Heap 分配的内存来执行此操作。总的来说,我的大部分代码都使用 Win32 API。 CRT 的东西只是作为模块内部的最后手段。而对于您的另一点,链接到 MFC dll 是最糟糕的事情。去过也做过。不再!您实际上是在依赖用户在其 System32 文件夹中拥有的“任何状态”DLL。最好的地狱地狱!
  • 嗯...不。 部署您的依赖项。进入您的应用程序的安装目录。如果您以正确的方式做事,就没有 DLL 地狱。这记录在Deploying Native Desktop Applications (Visual C++) 下。与 CRT 一样,动态链接 MFC 库为您提供了选项,否则这是不可能的。
  • 请注意,使用动态链接的 CRT 并不能完全解决在 DLL 边界之间传递 CRT 对象的问题 - 只有当应用程序中的所有模块都使用相同的 CRT DLL 时它才有效。如果可执行文件和所有 DLL 都是由同一供应商编写的,这通常不是什么大问题,但您仍然需要注意这一点。 (对于为第三方使用而分发的 DLL 更是如此。)
最近更新 更多