预处理器`_AFXDLL`是什么意思?

9

我已经搜索过,但没有找到一个有意义的解释,比如它的作用、机制,以便我能够理解它。一个“有意义的解释”的例子是,有很多在线材料解释_DEBUG预处理器,如何打开将允许使用assert等。

MSDN页面#1为Visual Studio 6.0构建MFC DLL的构建设置说这不是针对1)常规DLL,静态链接到MFCrequired,而是针对2)常规DLL,使用共享MFC DLL,或者3)扩展DLL所需的。但是没有进一步的解释。

MSDN页面#2 AFXDLL版本简要提到:

您可以通过构建应用程序来使用其中一个AFXDLL库,这些库包含了MFC在多个运行应用程序中可以共享的DLL中。有关AFXDLL名称的表格,请参见DLL:命名约定。

注意:默认情况下,MFC应用程序向导创建一个AFXDLL项目。要改为使用MFC代码的静态链接,请在MFC应用程序向导中设置“在静态库中使用MFC”选项。在Visual C++标准版中不提供静态链接。

但我甚至不确定这个AFXDLL是否与_AFXDLL预处理器相关。

Stackoverflow帖子Unexplainable error "Please use the /MD switch for _AFXDLL builds"#error Please use the /MD switch for _AFXDLL builds解释了/MT/MTd_AFXDLL冲突,但这与MSDN页面#1相同,没有新的内容。

有人能解释一下吗?

  • _AFXDLL预处理器是什么意思?最初的动机是什么?
  • 它如何影响编译或链接?
  • 它是否已经过时?
  • _AFXDLL预处理器是否与AFXDLL库相关?实际上,所谓的“AFXDLL库”是什么?

只是一个有教养的猜测:当您针对AFXDLL进行编译时,编译器是否定义了“_AFXDLL”?这样您就可以添加与目标相关的功能。 - Steeve
什么是AFXDLL? - athos
正如文档所述,当你使用MFC库时,你可以将它们静态链接到你的可执行文件中,或者从共享DLL中使用它们。在AFXDLL构建中,你将从共享DLL中使用它们。 - Steeve
1
概念是,当您使用库时,将存在许多已编译的代码,这些代码不在您实现的范围内。例如,当您使用MFC类时,这些类将在某个地方有一个实现,而不是在您的代码中。为了使它们工作,这些实现必须与您的可执行文件链接。您可以通过不同的方式实现这一点,其中一种方法是将MFC代码静态链接到您的可执行文件中,这意味着编译的代码将被添加到您的exe并成为其一部分。您可以将包含所使用的MFC代码的exe发送出去。 - Steeve
另一种方法是将MFC实现与您的可执行文件分开,并让您的可执行文件从DLL加载这些函数,这个MFC或AFX(相同名称)DLL(或DLLs)文件将位于用户系统的其他位置(通常是在_exe_文件旁边或Windows/System目录中)。MFC允许您双向链接它们的实现。 - Steeve
显示剩余2条评论
1个回答

23

MSVC++提供了一种优化方法,允许程序员只部署单个可执行文件。您可以使用 /MT 参数将 C 运行时库和标准 C++ 库链接到 EXE 文件中,并且您可以链接静态 MFC 库以将 MFC 链接到 EXE。对于小型 LOB 应用程序来说,这是很常见的。

这很不错,但是当您还使用 DLL 来模块化或共享代码或者更喜欢更快的构建时间时,这种方法可能无法正常工作。MFC(和 CRT)有很多全局状态,CWinApp 单例就是一个很好的例子。C++ 程序不像 Java 或 C# 应用程序那样在 VM 中运行,其中的一个模块必须负责存储该全局状态。而其他模块必须使用该模块的全局状态,而不是它们自己的全局状态。因此,您必须使用 MFC 的 DLL 版本和 C 和 C++ 运行时库的 DLL 版本,并链接它们的导入库,它们将承担起这个责任。

同时,您必须告诉编译器关于这些内容,以便库可以查找正确的位置存储这些全局状态。这需要 #define _AFXDLL。理解为“应用程序框架存在于其自己的 DLL 中”。CRT 也有一个宏,即 _DLL。

请注意,在 IDE 中这是完全自动的。在“项目” > “属性” > “常规” 中,“使用 MFC”设置中选择“在共享 DLL 中使用 MFC ”,则自动定义了 _AFXDLL。CRT 也是如此。


在IDE中,这是完全自动的吗?在项目>属性>常规中,“MFC使用”设置中,我选择“在共享DLL中使用MFC”,但我仍然看不到在项目>属性>C/C++>预处理器下定义了“_AFXDLL”? - athos
1
你需要深入查看,它是从项目属性表继承而来的。在VS2015中,单击设置的下拉按钮,编辑会显示在“继承值”框中。它也可以在C/C++ > 命令行 > 所有选项框中看到。 - Hans Passant

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