EEAddIn-Beispiel: Debuggen mit dem Ausdrucksauswertungs-Add-In
Aktualisiert: November 2007
Das EEAddin-Beispiel zeigt, wie die Ausdrucksauswertung des systemeigenen Debuggers mit der Add-In-API für die Ausdrucksauswertung erweitert wird.
Sicherheitshinweis: |
---|
Dieser Beispielcode dient dazu, ein Konzept zu veranschaulichen. Er sollte nicht für Anwendungen oder Websites verwendet werden, da dieser Code unter Umständen nicht die sicherste Codierungstechnik darstellt. Microsoft übernimmt keine Haftung für beiläufig entstandene Schäden oder Folgeschäden, falls der Beispielcode nicht bestimmungsgemäß verwendet wird. |
So rufen Sie Beispiele und Anweisungen für ihre Installation ab
Klicken Sie in Visual Studio im Menü Hilfe auf Beispiele.
Weitere Informationen finden Sie unter Suchen von Beispieldateien.
Die neueste Version und vollständige Liste mit Beispielen ist online unter Visual Studio 2008 Samples verfügbar.
Sie können auch Beispiele auf der Festplatte des Computers suchen. Standardmäßig werden Beispiele und eine Infodatei in einen Ordner unter \Programme\Visual Studio 9.0\Samples\ kopiert. Für Express Editions von Visual Studio sind alle Beispiele online verfügbar.
EE-Add-In-API (Add-In-API für die Ausdrucksauswertung)
Die Ausdrucksauswertung ist der Teil des Debuggers, der Ausdrücke interpretiert (auswertet). Wenn Sie einen Haltepunkt auf einen Ausdruck setzen oder einen Ausdruck in ein Debuggerfenster eingeben, interpretiert die Ausdrucksauswertung die Eingabe. Detaillierte Informationen finden Sie unter Ausdrücke im Debugger. Mit der Add-In-API zur Ausdrucksauswertung können Sie die Ausdrucksauswertung dahingehend erweitern, dass neue Typen verarbeitet werden können.
Wenn Sie die Ausdrucksauswertung für die Verarbeitung neuer Typen erweitern möchten, müssen Sie eine Funktion als Teil einer Win32-DLL schreiben (im gleichen Verzeichnis wie autoexp.dat) und über den Namen exportieren. Außerdem müssen Sie der autoexp.dat-Datei eine Zeile hinzufügen. Sie können die Ausdrucksauswertung auch für mehrere Typen erweitern, indem Sie mehrere Funktionen aus der DLL exportieren.
Erstellen und Ausführen des Beispiels
Die Schritte, die zum Erstellen und Ausführen dieses Beispiels erforderlich sind, lassen sich in drei Teile gliedern:
So erstellen Sie das Beispiel und führen es aus
Erstellen Sie eine DLL für das Ausdrucksauswertungs-Add-In (eeaddin.dll).
Bearbeiten Sie autoexp.dat dahingehend, dass es die Add-In-DLL zur Ausdrucksauswertung verwendet.
Testen Sie das Add-In, indem Sie ein Projekt erstellen, das den von autoexp.dat ausgewerteten benutzerdefinierten Datentyp verwendet.
In den folgenden Prozeduren werden diese Schritte ausführlich erörtert.
So erstellen Sie eine DLL für das Ausdrucksauswertungs-Add-In
Öffnen Sie in Visual Studio die Projektmappe eeaddin.sln.
Klicken Sie im Menü Erstellen auf die Option Erstellen.
Kopieren Sie die resultierende Datei eeaddin.dll in das Verzeichnis common7\ide
Wählen Sie im Menü Datei die Option Projektmappe schließen.
So bearbeiten Sie "autoexp.dat"
Zeigen Sie im Menü Datei auf die Option Öffnen, und klicken Sie auf Datei.
Suchen Sie im Dialogfeld Datei öffnen die Datei autoexp.dat (im Verzeichnis common7\packages\debugger), und klicken Sie auf Öffnen.
Bearbeiten Sie autoexp.dat, indem Sie die folgenden Zeilen hinzufügen:
_SYSTEMTIME=$ADDIN(eeaddin.dll,AddIn_SystemTime@28) _FILETIME=$ADDIN(eeaddin.dll,AddIn_FileTime@28)
Speichern Sie autoexp.dat.
So erstellen Sie ein Projekt, das die benutzerdefinierten Datentypen verwendet
Zeigen Sie im Menü Datei auf Neu, und klicken Sie auf Projekt.
Markieren Sie im Dialogfeld Neues Projekt die Option Visual C++-Projekte, und klicken Sie auf MFC-Anwendung. Geben Sie einen Namen für das Projekt ein, und klicken Sie auf OK.
Klicken Sie im MFC-Anwendungs-Assistenten auf Fertig stellen. Bei dem Projekt muss es sich um eine MFC-Anwendung handeln, da Sie im nächsten Schritt MFC-Funktionen hinzufügen.
Fügen Sie in der MFC-Anwendung ein SYSTEMTIME-Objekt oder ein FILETIME-Objekt hinzu.
SYSTEMTIME *s = new SYSTEMTIME(); FILETIME *f = new FILETIME(); GetSystemTime(s); SystemTimeToFileTime(s,f);
Klicken Sie im Menü Erstellen auf die Option Erstellen.
Starten Sie den Debugvorgang, und überprüfen Sie das SYSTEMTIME-Objekt bzw. das FILETIME-Objekt im Überwachungsfenster.
So funktioniert das Beispiel
Zum Erweitern der Ausdrucksauswertung für einen benutzerdefinierten Datentyp schreiben Sie eine benutzerdefinierte Viewerfunktion in die DLL für das Ausdrucksauswertungs-Add-In. Die Funktion verwendet einen Zeiger auf ein Objekt im Speicherplatz des Programms, das gedebuggt wird (nicht im Speicherplatz der Ausdrucksauswertung, die Sie gerade erweitern). Bei diesem Zeiger können Sie keine normalen Umwandlungen verwenden. Sie müssen den Zeiger und die Daten, auf die er zeigt, mit einer Rückruffunktion lesen. Ein Rückrufzeiger vom Typ DEBUGHELPER* zeigt auf ein Objekt mit verschiedenen Methoden.
Die Syntax sieht wie folgt aus:
HRESULT WINAPI CustomViewer(
DWORD dwAddress, // low 32-bits of address
DEBUGHELPER *pHelper, // callback pointer to access helper functions
int nBase, // decimal or hex
BOOL bIgnore, // not used
char *pResult, // where the result needs to go
size_t max, // how large the above buffer is
DWORD dwReserved // always pass zero
)
Dieses Beispiel enthält zwei Implementierungen dieses Funktionstyps: AddIn_SystemTime und AddIn_FileTime in timeaddin.cpp. Die (in custview.h definierte) DEBUGHELPER-Struktur umfasst Funktionszeiger, die Sie beim Schreiben der Erweiterung unterstützen. Dieser Zeiger wird an die CustomViewer-Funktion übergeben. Sie können ihn zum Aufrufen der Hilfsfunktionen verwenden.
Der Prozessortyp kann mit pHelper->GetProcessorType abgerufen werden. Es gibt zwei Methoden für den Lesezugriff auf den Speicher: pHelper->ReadDebuggeeMemory und pHelper->ReadDebuggeeMemoryEx. ReadDebuggeeMemoryEx verarbeitet 64-Bit-Adressen und wird vom Visual Studio .NET-Debugger unterstützt. ReadDebuggeeMemory verarbeitet keine 64-Bit-Adressen und wird von den Visual Studio .NET- und Visual C++ 6.0-Debuggern unterstützt. Wenn das Add-In nur für den Visual Studio .NET-Debugger geeignet ist, können Sie ReadDebuggeeMemoryEx verwenden. Wenn das Add-In auch bei Visual C++ 6.0 funktionieren soll, müssen Sie das dwVersion-Feld aktivieren und dürfen ReadDebuggeeMemoryEx nicht für Visual C++ 6.0 aufrufen.
Der folgende Code funktioniert bei beiden Debuggern und liest den Inhalt eines localobject (vom Typ MyType) aus dem Programm, das gerade gedebuggt wird:
DWORDLONG qwRealAddress;
DWORD dwGot;
MyType localobject;
if (pHelper->dwVersion<0x20000)
{
// Visual C++ 6.0 version
qwRealAddress = dwAddress;
pHelper->ReadDebuggeeMemory( pHelper, dwAddress,
sizeof(localobject), &localobject, &dwGot );
}
else
{
qwRealAddress = pHelper->GetRealAddress(pHelper);
pHelper->ReadDebuggeeMemoryEx( pHelper, qwRealAddress,
sizeof(localobject), &localobject, &dwGot );
}
// TODO: display localobject here
Bearbeiten von "autoexp.dat"
Die Zeilen, die Sie im Abschnitt [AutoExpand] von autoexp.dat einfügen, weisen folgende Syntax auf:
type=$ADDIN(dllname.dll,exportname)
Beispiel:
_SYSTEMTIME=$ADDIN(eeaddin.dll,AddIn_SystemTime)
oder:
_FILETIME=$ADDIN(eeaddin.dll,AddIn_FileTime)
Wenn die DLL sich nicht in dem Verzeichnis befindet, das devenv.exe enthält, oder in PATH, müssen Sie einen vollständigen Pfadnamen für die DLL verwenden. Beim exportname-Argument wird die Groß-/Kleinschreibung berücksichtigt. Es muss genau dem exportierten Namen entsprechen, den Sie bei der Ausführung von dumpbin –exports für die DLL erhalten haben.
Zum Testen des Debuggers mit dem neuen Add-In beenden Sie zunächst alle Debugvorgänge für Programme, die bei der Installation der neuen DLL gedebuggt wurden, und starten dann eine neue Debugsitzung.
Hinweis Das Add-In wird innerhalb des Debuggers ausgeführt. Wenn der Code also nach einer Fehlfunktion beendet wird, wird auch die IDE beendet.