Rebuilding MFC and CRT
2007-06-29 18:04
323 查看
http://www.trigeminal.com/usenet/usenet034.asp
Building the Unicode version of MFC is slightly easier than building the CRT. The Unicode version of MFC is actually 5 different DLLs:
MFC42U.DLL (Unicode Release)
MFC42UD.DLL (Unicode Debug)
MFCN42UD.DLL (Unicode Debug - Network classes)
MFCO42UD.DLL (Unicode Debug - OLE classes)
MFCD42UD.DLL (Unicode Debug - Database classes)
Notice that the release version is a single DLL whereas the debug version is split up into 4 different DLLs. Presumably, this was done to reduce load times when debugging. This makes it a little less straightforward that it should be.
To build MFC, there are 4 provided Makefiles in the VC98/MFC/SRC folder named:
MFCDLL.MAK
MFCNET.MAK
MFCOLE.MAK
MFCDB.MAK
The MFCDLL.MAK builds the first two DLLs, and each of the others builds the rest.
First, we will change each of the 4 .MAK files to link to Unicows.lib. In each file, after the line that states:
insert the following two lines:
They must go in that position, if we don't do this then a library reference will be included causing unicows.lib to be linked after kernel32.lib (which will then cause the unicows.dll load to fail). Other DLLs in the wrong order will simply cause APIs in those specific DLLs to not be called.
The line numbers to insert the above two lines after are:
MFCDLL.MAK - line 206
MFCNET.MAK - line 134
MFCOLE.MAK - line 134
MFCDB.MAK - line 140
Now, we will decide what to name our new DLL. We do not want to use the standard name(s) for the same reasons we did not use the standard names for the CRT. So we will come up with a simple naming convention: we'll add an "L" to the name. So the new names will be:
MFC42LU.DLL
MFC42LUD.DLL
MFCN42LUD.DLL
MFCO42LUD.DLL
MFCD42LUD.DLL
We are going over the 8.3 naming convention here, but only for some of the debug builds which we will not be shipping, so we should be fine.
Now we need to change the following three files to match our naming. MFC does a LoadLibrary and has hard-coded each of the above DLL names to our new names in the following files: DLLDB.CPP, DLLNET.CPP, and DLLOLE.CPP.
In DLLDB.CPP, change lines 38,39, 46, and 47, i.e.
In DLLNET.CPP, change lines 37 and 43, i.e.
In DLLOLE.CPP, change lines 38 and 44, i.e.
Now we need to change the hard-coded reference to the name of the CRT. Since we changed it when rebuilt the CRT, we need to change the following file: DLLINIT.CPP.
In DLLINIT.CPP, change lines 371 and 373, i.e.
While we're in DLLINIT.CPP we need to get rid of the block that prevents loading of MFC (if we haven't already done so). Change the line 391 from #ifdef _UNICODE to #if 0 (this will prevent that piece of code from being included). For more info on this issue and other MFC/MSLU issues, click here.
Since we renamed the DLLs, we need to rename the DEF files that are linked to the DLLs. They are located in the VC98/MFC/SRC/INTEL folder. i.e.
We need to open each of the above new DEF files up in notepad and change the LIBRARY line to match the name of the DEF file.
Now we're ready to build the versions of MFC:
Create a new batch file called buildmfc.bat in the MFC/SRC folder with the following content:
Above we are building a release and debug versions of the main DLL (MFC42LU(D).DLL), and debug versions of the rest.
Run the batch file, and then you will be done. If you need to rebuild any time in the future you now have a convenient batch file to do so. The DLL files will be created in the VC98/MFC/SRC folder. The LIB and PDB files will be created in the MFC/LIB folder.
After the building is done, we need to copy the created LIBs in the VC98/MFC/LIB folder back to their original names (overwriting what's there) so that any of our apps that we link will use the new DLLs. i.e.
The reason we do this is the same as for the CRT: we don't have to worry about changing any linker options in our projects to link to the new version of MFC.
Now we're ready to do a test build of an application. Create a new SDI MFC application using the AppWizard, choose dynamic MFC, create a Unicode Debug and Release build, change the settings to link to unicows.lib, copy the newly created CRT and MFC DLLs to your DEBUG or RELEASE build folder(s) and then run the application. It should all work.
Use dependency walker to make sure that everything is getting linked properly and the proper DLLs are being loaded (run a profile in dependency walker). No references to the old names of the DLLs for both the CRT or MFC should be there.
Building MFC Unicode version with MSLU
First we will make a backup of the following folders (and all subfolders of): VC98/MFC/LIB, and VC98/MFC/SRC so we can restore them later if necessary.Building the Unicode version of MFC is slightly easier than building the CRT. The Unicode version of MFC is actually 5 different DLLs:
MFC42U.DLL (Unicode Release)
MFC42UD.DLL (Unicode Debug)
MFCN42UD.DLL (Unicode Debug - Network classes)
MFCO42UD.DLL (Unicode Debug - OLE classes)
MFCD42UD.DLL (Unicode Debug - Database classes)
Notice that the release version is a single DLL whereas the debug version is split up into 4 different DLLs. Presumably, this was done to reduce load times when debugging. This makes it a little less straightforward that it should be.
To build MFC, there are 4 provided Makefiles in the VC98/MFC/SRC folder named:
MFCDLL.MAK
MFCNET.MAK
MFCOLE.MAK
MFCDB.MAK
The MFCDLL.MAK builds the first two DLLs, and each of the others builds the rest.
First, we will change each of the 4 .MAK files to link to Unicows.lib. In each file, after the line that states:
link @<<
insert the following two lines:
/nod:kernel32.lib /nod:advapi32.lib /nod:user32.lib /nod:gdi32.lib /nod:shell32.lib /nod:comdlg32.lib /nod:version.lib /nod:mpr.lib /nod:rasapi32.lib /nod:winmm.lib /nod:winspool.lib /nod:vfw32.lib /nod:secur32.lib /nod:oleacc.lib /nod:oledlg.lib /nod:sensapi.lib unicows.lib kernel32.lib advapi32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib version.lib mpr.lib rasapi32.lib winmm.lib winspool.lib vfw32.lib oleacc.lib oledlg.lib
They must go in that position, if we don't do this then a library reference will be included causing unicows.lib to be linked after kernel32.lib (which will then cause the unicows.dll load to fail). Other DLLs in the wrong order will simply cause APIs in those specific DLLs to not be called.
The line numbers to insert the above two lines after are:
MFCDLL.MAK - line 206
MFCNET.MAK - line 134
MFCOLE.MAK - line 134
MFCDB.MAK - line 140
Now, we will decide what to name our new DLL. We do not want to use the standard name(s) for the same reasons we did not use the standard names for the CRT. So we will come up with a simple naming convention: we'll add an "L" to the name. So the new names will be:
MFC42LU.DLL
MFC42LUD.DLL
MFCN42LUD.DLL
MFCO42LUD.DLL
MFCD42LUD.DLL
We are going over the 8.3 naming convention here, but only for some of the debug builds which we will not be shipping, so we should be fine.
Now we need to change the following three files to match our naming. MFC does a LoadLibrary and has hard-coded each of the above DLL names to our new names in the following files: DLLDB.CPP, DLLNET.CPP, and DLLOLE.CPP.
In DLLDB.CPP, change lines 38,39, 46, and 47, i.e.
#define MFC42_DLL "MFC42LUD.DLL" #define MFCO42_DLL "MFCO42LUD.DLL" #define MFC42_DLL "MFC42LU.DLL" #define MFCO42_DLL "MFCO42LU.DLL"
In DLLNET.CPP, change lines 37 and 43, i.e.
#define MFC42_DLL "MFC42LUD.DLL" #define MFC42_DLL "MFC42LU.DLL"
In DLLOLE.CPP, change lines 38 and 44, i.e.
#define MFC42_DLL "MFC42LUD.DLL" #define MFC42_DLL "MFC42LU.DLL"
Now we need to change the hard-coded reference to the name of the CRT. Since we changed it when rebuilt the CRT, we need to change the following file: DLLINIT.CPP.
In DLLINIT.CPP, change lines 371 and 373, i.e.
#define MSVCRT_DLL "MSLURTD.DLL" #define MSVCRT_DLL "MSLURT.DLL"
While we're in DLLINIT.CPP we need to get rid of the block that prevents loading of MFC (if we haven't already done so). Change the line 391 from #ifdef _UNICODE to #if 0 (this will prevent that piece of code from being included). For more info on this issue and other MFC/MSLU issues, click here.
Since we renamed the DLLs, we need to rename the DEF files that are linked to the DLLs. They are located in the VC98/MFC/SRC/INTEL folder. i.e.
copy MFC42U.DEF MFC42LU.DEF copy MFC42UD.DEF MFC42LUD.DEF copy MFCN42UD.DEF MFCN42LUD.DEF copy MFCO42UD.DEF MFCO42LUD.DEF copy MFCD42UD.DEF MFCD42LUD.DEF
We need to open each of the above new DEF files up in notepad and change the LIBRARY line to match the name of the DEF file.
Now we're ready to build the versions of MFC:
Create a new batch file called buildmfc.bat in the MFC/SRC folder with the following content:
nmake -f mfcdll.mak libname=MFC42L DEBUG=0 UNICODE=1 /a nmake -f mfcdll.mak libname=MFC42L DEBUG=1 UNICODE=1 /a nmake -f mfcdb.mak libname=MFCD42L DEBUG=1 UNICODE=1 /a nmake -f mfcnet.mak libname=MFCN42L DEBUG=1 UNICODE=1 /a nmake -f mfcole.mak libname=MFCO42L DEBUG=1 UNICODE=1 /a
Above we are building a release and debug versions of the main DLL (MFC42LU(D).DLL), and debug versions of the rest.
Run the batch file, and then you will be done. If you need to rebuild any time in the future you now have a convenient batch file to do so. The DLL files will be created in the VC98/MFC/SRC folder. The LIB and PDB files will be created in the MFC/LIB folder.
After the building is done, we need to copy the created LIBs in the VC98/MFC/LIB folder back to their original names (overwriting what's there) so that any of our apps that we link will use the new DLLs. i.e.
copy MFC42LU.LIB MFC42U.LIB copy MFC42LUD.LIB MFC42UD.LIB copy MFCN42LUD.LIB MFCN42UD.LIB copy MFCO42LUD.LIB MFCO42UD.LIB copy MFCD42LUD.LIB MFCD42UD.LIB
The reason we do this is the same as for the CRT: we don't have to worry about changing any linker options in our projects to link to the new version of MFC.
Now we're ready to do a test build of an application. Create a new SDI MFC application using the AppWizard, choose dynamic MFC, create a Unicode Debug and Release build, change the settings to link to unicows.lib, copy the newly created CRT and MFC DLLs to your DEBUG or RELEASE build folder(s) and then run the application. It should all work.
Use dependency walker to make sure that everything is getting linked properly and the proper DLLs are being loaded (run a profile in dependency walker). No references to the old names of the DLLs for both the CRT or MFC should be there.
相关文章推荐
- Win32 CRT and MFC 清单文件.manifest配制
- Win32 CRT and MFC 清单文件.manifest配制
- A LNK2005 error occurs when the CRT library and MFC libraries are linked in the wrong order in Visua
- When the C Run-Time (CRT) library and Microsoft Foundation Class (MFC) libraries are linked in the w
- A LNK2005 error occurs when the CRT library and MFC libraries are linked in the wrong order in Visual C++
- A LNK2005 error occurs when the CRT library and MFC libraries are linked in the wrong order in Visual C++
- How to solve problem caused when the CRT library and MFC libraries are linked in the wrong order
- zz : A LNK2005 error occurs when the CRT library and MFC libraries are linked in the wrong order in Visual C++ ---- nafxcw.lib(a
- fatal error C1189: #error : Building MFC application with /MD[d] (CRT dll version) requires MFC sha
- openssl key and crt
- WTL for MFC Programmers, Part IX - GDI Classes, Common Dialogs, and Utility Classes
- MFC DLL—Regular DLL and Extension DLL
- 《基于MFC的OpenGL编程》Part 6 Keyboard and Mouse Control
- Information About The Space of MFC and C#,ASP.NET
- MFC Macros and Globals
- Reading and Writing CSV Files in MFC
- The different between Char in C#.Net and in C++.Net(MFC)
- 错误的顺序链接 CRT 库和 MFC 库时出现 LNK2005 错误
- fatal error C1189: #error : Building MFC application with /MD[d] (CRT dll version) requires MFC sha
- 《基于MFC的OpenGL编程》Part 11 Blending, Antialiasing and Fog