There is one crucial step missing from the supplied MFC makefiles. If you take a look at
line 425 of …vc7\mfc\makefile, you’ll see that one of the options passed to the compiler is
/Zc:wchar_t, which causes wchar_t to become an implicit type. This may be what you want, but
if the application you’re linking the lib to wasn’t compiled with this same option (and --
therefore -- has wchar_t #defined to unsigned short), you will get unresolved externals when
you link. Your program is looking for function signatures with unsigned shorts in them, but
the lib only exports wchar_t in the function signatures.
You could remove the /Zc:wchar_t from the makefile, but this solution isn’t universal; it
would still prevent linking with programs compiled with the /Zc:wchar_t switch.
A better solution is to do what Microsoft did in the original mfc70 libraries: include alias
records in the library so that you can link both implicit wchar_t and unsigned short programs.
Alias records allow a library to export multiple function signatures that resolve down to the
same object code.
So how do you add alias records to your newly-built MFC libraries?
For both the debug and release MFC library libraries you need to do the following:
a) Extract all of the alias records from the corresponding retail MFC library
b) Create a new library comprising only these alias records
c) Merge your new Unicows-compliant MFC library with the associated alias-record library
Step A)
This one requires a small detour because lib.exe only allows you to extract one object at a time.
We want to automate this step by creating a batch file to do all of the extractions.
First, get a command prompt and make …\Vc7\atlmfc\lib your current directory. Next, create a list
of all of the alias records in both debug and release MFC libs using the following two command lines:
lib /LIST mfc70ud.lib > mfc70ud.lib.lst
lib /LIST mfc70u.lib > mfc70u.lib.lst
You should now have the two .lib.lst files that each contain a list of library objects, one per line.
Now, we will create a perl script to build a pair of batch files from the .lib.lst files (if you don’t
already have perl, it’s freely available from several sources. You can find Perl
here).
Start up a text editor and enter the following text:
#!/usr/bin/perl
# builds a batch file to extract all alias records
# in the input file (input file created with lib.exe /LIST)
$targetLib = "mfc70ud.lib";
$outDir = "_aliasRecordsD";
print "md .\\$outDir\n";
while (<>)
{
# find alias record name
if (/_alias[0-9]+\.obj/)
{
chop;
print "LIB /EXTRACT:$_ /OUT:.\\$outDir\\$_ $targetLib\n";
}
}
Save the text as BuildAliasExtractBatchD.pl.
Now edit the text so that the $targetLib variable is changed as follows:
$targetLib = "mfc70u.lib";
also change $outDir as shown:
$outDir = “_aliasRecords";
Save the edited text as BuildAliasExtractBatch.pl.
Now run the two perl scripts as follows from the command prompt:
perl BuildAliasExtractBatchD.pl mfc70ud.lib.lst > BuildAliasExtractD.bat
perl BuildAliasExtractBatch.pl mfc70u.lib.lst > BuildAliasExtract.bat
At this point you have two batch files, one of which will extract the alias records from the debug library
and one that will extract from the release library.
To complete step a) all that’s left is to run the batch files. Note that there are about 2000 alias records
in each MFC library, and extracting them one by one is a slow process; each library extraction took about 4
hours on a fast PC.
At the completion of this step, you will have two new directories under …\vc7\atlmfc\lib each of which
contains extracted alias records. Each extracted alias record is a file with a name of the form _alias*.obj
where * is one to four decimal digits.
Step B)
For Step b), we want to create a new library from the extracted records. Fortunately, this can be done in two
simple steps; in contrast to Step a) we can use a response file with lib.exe to simplify our operation.
First, we create a pair of perl scripts that will build the response files.
Use your favorite text editor to enter the following text:
#!/usr/bin/perl
# builds a response file for lib.exe to build a library of
# alias records. (input file created with lib.exe /LIST)
$outLib = "mfc70udAlias.lib";
$aliasDir = "_aliasRecordsD";
print "/OUT:$outLib";
while (<>)
{
# find alias record name
if (/_alias[0-9]+\.obj/)
{
chop;
print " .\\$aliasDir\\$_";
}
}
Save the file as CreateAliasLibD.pl.
Now edit the variable declarations so they read:
$outLib = "mfc70uAlias.lib";
$aliasDir = "_aliasRecords";
and save the file as CreateAliasLib.pl
Run the perl scripts from the command line. Note that we reuse the .lib.lst files we created in Step A)
as input here:
perl CreateAliasLibD.pl mfc70ud.lib.lst > mfc70udAlias.rsp
perl CreateAliasLib.pl mfc70u.lib.lst > mfc70uAlias.rsp
With the response files made, we now use them with lib.exe to create the alias libraries:
lib @mfc70udAlias.rsp
lib @mfc70uAlias.rsp
At the completion of this step you will have two new libraries: mfc70udAlias.lib and mfc70uAlias.lib. They will each
contain their respective alias records.
Step C)
In this step, we simply merge our custom-built MFC libraries with the alias libraries we just made. While
we’re at it, we’ll also rename the libraries so they’ll replace the original libraries. Note that we get our
custom-built libraries directly from their output locations.
lib /OUT:mfc70ud.lib .\Intel\MFC70LUD.lib mfc70udAlias.lib
lib /OUT:mfc70u.lib .\Intel\MFC70LU.lib mfc70uAlias.lib