Using LIMODS

[Previous] [Next]

Before reading any further, you need to install LIMODS. All the source code for LIMODS is on the book's companion CD, and you'll need to compile the entire LIMODS project. After compiling, copy the LIMODS settings file, LIMODS.INI, to your %SYSTEMROOT% or Windows directory. By default, LIMODS will place its data files (LOM) in the same directory in which each loaded module resides when LIMODS is active. If you set the LOMDirectory in the [LIMODS] section of LIMODS.INI, GENLIMODS.EXE will place all generated LOM files in one directory. I use this setting because I prefer to have all the LOM files sent to one location instead of scattered all over my hard drive. After taking care of the settings file, you need to put the binary files—LIMODSDLL.DLL, BUGSLAYERUTIL.DLL, GENLIMODS.EXE, and LIMODS.EXE—in a directory specified by your PATH environment variable.

Living with MFC

If you want to use LIMODS with an application that uses either MFC42D.DLL or MFC42UD.DLL, you'll need to take an extra step to install it. Unfortunately, there must be at least 1,001 versions of those two very important DLLs. LIMODS must know which ordinal value corresponds to the exported AfxTrace function from each of the MFC DLLs. Although you'd think that AfxTrace would always have the same ordinal value regardless of which DLL it's in, it doesn't. The distributed LIMODS.INI holds the information for MFC42(U)D.DLL that's used with Visual C++ 5 with no service packs, Visual C++ 6 with no service packs, Visual C++ 6 with Service Pack 1 (SP1), Visual C++ 6 with Service Pack 2 (SP2), and Visual C++ 6 with Service Pack 3 (SP3).

If you're using a version of Visual C++ different from the ones listed in LIMODS.INI (including any subsequent service pack releases), you'll need to do some additional work to ensure that LIMODS gets the right export out of MFC42D.DLL and MFC42UD.DLL. You can find the version information for %SYSTEMROOT%\System32\MFC42(U)D.DLL by right-clicking on it in Windows Explorer and selecting Properties from the pop-up menu. Click the Version tab in the Properties dialog box; the first item, File Version, is the number you want. For example, the version of MFC42D.DLL that Visual C++ 6.0 SP3 uses is 6.00.8447.0.

Next change to the \MFC\SRC\Intel directory in your Visual C++ installation. There you'll find the DEF files used to link MFC. Each DEF file name corresponds to a binary file name. For example, MFC42D.DEF is the matching DEF file for MFC42D.DLL. Open the appropriate DEF file, and for MFC42D.DLL, search for the text ?AfxTrace@@YAXPBDZZ. For MFC42UD.DLL, search for the text ?AfxTrace@@YAXPBGZZ. The important line will look like this:

?AfxTrace@@YAXPBDZZ @ 1179 NONAME

The number after the @ sign is the ordinal value of the exported AfxTrace function. Remember this number—you'll need to enter this ordinal value into the LIMODS.INI file.

Open your copy of LIMODS.INI. For MFC42D.DLL, look for the section [MFC42D.DLL Hack-O-Rama]. For MFC42UD.DLL, the section is [MFC42UD.DLL Hack-O-Rama]. The section for MFC42D.DLL will look like the following, and it's nearly identical to the section for MFC42UD.DLL:

[MFC42D.DLL Hack-O-Rama] VerCount=3 ; VC 6.0 SP3 Ver0=6.00.8447.0,1179 ; VC 6.0 SP1 and SP2. Ver1=6.00.8267.0,1179 ; VC 6.0 NO SERVICE PACKS Ver2=6.00.8168.0,1179

The Vern lines show the version number and ordinal value information. The first number is the MFC file version number, and the second number is the AfxTrace ordinal value.

Add your MFC file version and AfxTrace ordinal value as the next line in the [MFC42D.DLL Hack-O-Rama] or [MFC42UD.DLL Hack-O-Rama] section. For example, if you're working with Visual C++ 5 with no service packs, you'd add the line Ver3=4.21.7022,1253 to the preceding sample for MFC42D.DLL. You'd also need to increment the right-hand side of VerCount. For MFC42UD.DLL in Visual C++ 5 with no service pack, the line would be Ver3=4.21.7022,1256.

If you modify the MFC source code and build your own private MFC42(U)D.DLL, you can check the ordinal value information in the same way as I described earlier. I'd suggest, however, that you never change the MFC source code and create your own MFC version—unless, of course, you feel like manually updating every MFC bug fix into your version of the source files.

LIMODS validates the MFC file version when MFC42(U)D.DLL is loaded into memory. If you don't have the corresponding file version in LIMODS.INI, you'll get an error message in the Output window, accompanied by a few beeps. If you compile and run the LIMODS test program in the \SoureCode\LIMODS\TestLIMODS directory on the companion CD, you'll quickly find out whether you configured LIMODS correctly.

Calling LIMODS from Your Code

After all the hoops you had to jump through to ensure that you're using the correct MFC DLL, you might find it almost a letdown when I tell you that for C/C++ programs, the following line of code is the only one you need to add to your program to get LIMODS working:

LoadLibrary ( "LIMODSDLL.DLL" ) ;

LIMODSDLL.DLL works all its magic in its DllMain, so you don't need to call any other functions. I figure adding one line of code isn't too much to ask to reap the benefits of LIMODS.

If you're developing in Visual Basic, getting LIMODS to work in your code is a little more complicated—but not by much. First you'll need to copy LIMODS.CLS and INDESIGNMOD.BAS out of the \SourceCode\LIMODS\VB directory from the companion CD and add them to your project. Then you'll need to create a global instance of the clsLIMODS class, shown in Listing 14-1. I'd recommend naming the global instance variable something like cLIMODS. The clsLIMODS class has only one method; it's named (surprise) Trace, and it takes the same input as the Debug.Print method. There's no way to intercept the internal Debug.Print object, so you must compile your application for LIMODS to work. When you run from the Visual Basic integrated development environment (IDE), the clsLIMODS Trace method will resolve to a Debug.Print call, so you'll still be able to see trace statement output in the Immediate window.

You'll also need to define the conditional compilation option LIMODS=-1 in your project so that you get the appropriate class functions when you compile. If you don't define the conditional compilation, you get the empty versions. By using the conditional compilation, you won't have to pay the full overhead for LIMODS when you don't need it, although you'll still get the empty function overhead. To avoid the cost of the empty functions, you'll need to wrap all your calls to the clsLIMODS object in conditional compilation.

Listing 14-1 LIMODS.CLS

VERSION 1.0 CLASS BEGIN MultiUse = -1 'True Persistable = 0 'NotPersistable DataBindingBehavior = 0 'vbNone DataSourceBehavior = 0 'vbNone MTSTransactionMode = 0 'NotAnMTSObject END Attribute VB_Name = "clsLIMODS" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = True Attribute VB_PredeclaredId = False Attribute VB_Exposed = False '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Copyright (c) 1997-2000 John Robbins -- All rights reserved. ' "Debugging Applications" (Microsoft Press) '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' The LIMODS helper class for Visual Basic development ' 1. Include this class file in your Visual Basic project. Create a ' global instance of this class in your project. (I'd name the global ' instance variable "cLIMODS".) ' 2. Just call cLIMODS.Trace to direct trace statements through here. ' 3. LIMODS is active only with compiled Visual Basic. If you run this ' class under the Visual Basic IDE debugger, your trace statements ' will be sent through the regular Debug.Print trace statement. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Option Explicit Private Declare Function LoadLibrary Lib "kernel32" _ Alias "LoadLibraryA" _ (ByVal lpLibFileName As String) As Long Private Declare Sub OutputDebugString Lib "kernel32" _ Alias "OutputDebugStringA" _ (ByVal lpOutputString As String) Private Declare Function GetModuleFileName Lib "kernel32" _ Alias "GetModuleFileNameA" _ (ByVal hModule As Long, _ ByVal lpFileName As String, _ ByVal nSize As Long) As Long Private Declare Function GetModuleHandle Lib "kernel32" _ Alias "GetModuleHandleA" _ (ByVal lpModuleName As String) As Long Private m_IsInIDE As Boolean #If LIMODS Then Private Sub Class_Initialize() Dim bIsInIDE As Boolean bIsInIDE = InDesign() ' If bIsInIDE is False, the main module isn't the Visual Basic IDE, ' so I can load LIMODSDLL.DLL. If (False = bIsInIDE) Then LoadLibrary "LIMODSDLL.DLL" m_IsInIDE = False Else m_IsInIDE = True End If End Sub #End If #If LIMODS Then Public Sub Trace(sOut As Variant) If (True = m_IsInIDE) Then Debug.Print sOut Else Dim s As String s = sOut OutputDebugString s End If End Sub #Else ' LIMODS is *not* conditionally defined. Public Sub Trace(sOut As Variant) End Sub #End If

Selecting Which Source Files to Trace From

All the LOM files for modules compiled with debug symbols will be generated the first time you run with LIMODSDLL.DLL loaded, so you'll experience a slight pause in your application as they're being processed. LIMODS keeps the LOM files up to date as your modules change, so you don't have to worry about tracking these changes manually. If you prefer, you can generate the LOM files as part of your normal build process by using GENLIMODS.EXE. Just run GENLIMODS.EXE without any command-line parameters to see a description of its use.

After the LOM files are loaded, simply run LIMODS.EXE and select which source files from which modules you want to view. Figure 14-1 shows LIMODS.EXE in action. Select the check box next to the source files from which you want to see trace statements.

click to view at full size.

Figure 14-1 LIMODS.EXE in action



Debugging Applications
Debugging Applications for MicrosoftВ® .NET and Microsoft WindowsВ® (Pro-Developer)
ISBN: 0735615365
EAN: 2147483647
Year: 2000
Pages: 122
Authors: John Robbins

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net