Rebuilding MFC and CRT

http://www.trigeminal.com/usenet/usenet034.asp

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.

  1. 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

  2. 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.

  3. 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"
    
  4. 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"
    
  5. 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.

  6. 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
    
  7. 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.

  8. 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.

  9. 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.  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章