9
votes

I've searched but didn't hit a meaningful explanation, like what's the effect, the mechanism, so I could understand it. An example for "meaningful explanation", there are quite some materials online explaining _DEBUG preprocessor, how turn it on will allow assert etc.

MSDN page #1 Building Settings for an MFC DLL for Visual Studio 6.0 says this is not for 1) Regular DLL, statically linked to MFCrequired, but required for 2) Regular DLL, using the shared MFC DLL, or, for 3) Extension DLL. But there's no further explanation.

MSDN page #2 AFXDLL Versions briefly mentioned:

Instead of building your application by statically linking to the MFC object-code libraries, you can build your application to use one of the AFXDLL libraries, which contain MFC in a DLL that multiple running applications can share. For a table of AFXDLL names, see DLLs: Naming Conventions.

Note: By default, the MFC Application Wizard creates an AFXDLL project. To use static linking of MFC code instead, set the Use MFC in a static library option in the MFC Application Wizard. Static linking is not available in the Standard Edition of Visual C++.

, but I'm even not sure if this AFXDLL is related to _AFXDLL preprocessor.

Stackoverflow post Unexplainable error "Please use the /MD switch for _AFXDLL builds" and #error Please use the /MD switch for _AFXDLL builds explained that /MT or /MTd conflict with _AFXDLL, but this is the same as the MSDN page #1, nothing new.

Could someone pls explain

  • what does _AFXDLL preprocessor mean? the original motivation?
  • how does it affect the compiling or linking?
  • is it obsolete?
  • is _AFXDLL preprocessor related to the AFXDLL libraries? and actually, what is this so called "AFXDLL library"?
1
Just an educated guess: Isn't _AFXDLL defined by the compiler when you are compiling against an AFXDLL? Just so you can add target-dependent functionality. - Steeve
what is AFXDLL? - athos
As the documentation states, when you are using the MFC libraries, you can either statically link them to your executable, or you can use them from a shared DLL. With an AFXDLL build you'll be using them from a shared DLL. - Steeve
"from a shared DLL"... which DLL? if I'm not developing a DLL, but an EXE, shall I set _AFXDLL or not? - athos
The concept is that when you use a library there will be a lot of compiled code outside of what you have implemented. Like, for example when you use MFC classes, these will have an implementation somewhere, not in your code. These implementations will have to be linked with your executable in order to work. You can achieve this in different ways, one way is to link the MFC code with your executable statically, meaning that the compiled code will be added to your exe and be a part of it. You can ship your exe with the MFC code inside it that you are using. - Steeve

1 Answers

21
votes

MSVC++ provides an optimization for programmers that want to deploy only a single executable file. You can build with /MT to link the C runtime library and the standard C++ library into the EXE. And you can link the static MFC libraries to link MFC into the EXE. Not uncommon for small LOB apps.

Nice, but that cannot work properly when you also use DLLs to modularize or share your code or favor faster build times. MFC (and the CRT) have lots of global state, the CWinApp singleton is a good example. A C++ program does not run in a VM like Java or C# apps do, one of the modules has to take responsibility to store that global state. And the other modules must use that module's globals, not their own. So you must use the DLL version of MFC and the DLL version of the C and C++ runtime libraries, and link their import libraries, they take on that responsibility.

And you have to tell the compiler about it, so that the library will go looking for the right place for those globals. That requires #defining _AFXDLL. Read it like "the application framework lives in its own DLL". The CRT has a macro for that as well, it is _DLL.

Do note that this is completely automatic in the IDE. Project > Properties > General, "Use of MFC" setting. If you pick "Use of MFC in a Shared DLL" for this setting then you automagically will also get _AFXDLL defined. Same for the CRT.