|A few days ago, I created an ATL (with MFC support) DLL project. The project compiled properly with absolutely no problem.
Then today, after doing some code modifications (which, believe me, were trivial and innocuous), I was confronted with the link error LNK1169 : Multiple Symbols Defined.
The problem was that while linking with mfcs42.lib, the linker noticed that this library contains a DEFINITION (i.e. full code, and not just a reference) of the function _DllMain@12. However, it also noted that the same function _DllMain@12 was already defined inside MSVCRTD.lib.
After some research and testing, I discovered the following facts regarding DllMain() when used in the context of a DLL project in which MFC is used :
1. Because MFC is used, a CWinApp class will be generated. This is so that the DLL application startup and shutdown processes can be abstracted by the CWinApp class (e.g. the use of InitInstance() and ExitInstance(), etc).
2. For this to happen, MFC must have its own version of DllMain() which will initialize the CWinApp class etc. Hence, this (MFC's) DllMain() must be the one eventually used (i.e. linked-to) by the Dll.
3. The MSVC runtime libraries also include their own versions of DllMain(). This being the case, potential conflicts can happen.
4. Such multiple-defined symbol link errors normally do not cause any problems because the linker will use the function that it finds first in its list of libraries.
5. It is still unclear to me why this link error occurred but this is a blessing in disguise because had this error not appeared, the DllMain() defined inside MSVCRTD.LIB would have been used and there will be problems : i.e. my CWinApp class will not be properly initialized.
The solution to the above problem is to make sure that MFC's DllMain() is discovered first by the linker during linkage.
The way to do this in VC++ 6.0 is to go to the Project Settings, go to the "Link" tab, go to the "General" category, type in the name of the appropriate MFC library (e.g. mfcs42.lib, in my case) in the "Object/library modules" box. If the competing library (i.e. msvcrtd.lib in my case) is also in the box, make sure that the target MFC library is placed BEFORE the competing library.
Note that in my case, simply typing mfcs42.lib in the box ensured that this library is used first. Msvcrtd.lib was not in the box and so I did not have to put it there either.
Hope this helps others.
modified on Friday, May 9, 2008 7:52 AM