EEAddIn, exemple : débogage du complément Évaluateur d'expression
Mise à jour : novembre 2007
L'exemple EEAddin montre comment étendre l'évaluateur d'expression du débogueur natif à l'aide de l'API du complément Évaluateur d'expression.
Note de sécurité : |
---|
Cet exemple de code est fourni pour illustrer un concept et ne doit pas être utilisé dans des applications ou des sites Web, car il peut ne pas illustrer les pratiques de programmation les plus sûres. Microsoft n'assume aucune responsabilité pour tout dommage indirect ou consécutif en cas d'utilisation de l'exemple de code à des fins autres que celles prévues. |
Pour obtenir des exemples et des instructions d'installation :
Dans le menu Aide de Visual Studio, cliquez sur Exemples.
Pour plus d'informations, consultez Recherche des fichiers d'exemple.
La liste la plus récente et la plus complète d'exemples est disponible en ligne à partir de la page d'exemples Visual Studio 2008 (en anglais).
Des exemples sont également disponibles sur le disque dur de votre ordinateur. Par défaut, des exemples et un fichier Readme sont copiés dans un dossier sous \Program Files\Visual Studio 9.0\Samples\. Pour les éditions Express de Visual Studio, tous les exemples sont accessibles en ligne.
API du complément Évaluateur d'expression
L'évaluateur d'expression est la partie du débogueur qui interprète (évalue) les expressions. Lorsque vous définissez un point d'arrêt dans une expression ou tapez une expression dans une fenêtre de débogage, l'évaluateur d'expression interprète les données entrées. Pour plus d'informations, consultez Expressions dans le débogueur. Avec l'API du complément Évaluateur d'expression, vous pouvez étendre l'évaluateur d'expression pour qu'il gère de nouveaux types.
Pour étendre l'évaluateur d'expression à un nouveau type, vous devez écrire une fonction dans le cadre d'une DLL Win32 (dans le même répertoire que le fichier autoexp.dat) et l'exporter par son nom. Vous devez également ajouter une ligne au fichier autoexp.dat. Vous pouvez étendre l'évaluateur d'expression à plusieurs nouveaux types en exportant plusieurs fonctions à partir de la DLL.
Génération et exécution de l'exemple
Les étapes nécessaires pour générer et exécuter cet exemple peuvent être regroupées en trois phases.
Pour générer et exécuter l'exemple
Générez une DLL du complément Évaluateur d'expression (eeaddin.dll).
Modifiez autoexp.dat pour utiliser la DLL du complément Évaluateur d'expression.
Testez le complément en créant un projet qui utilise le type de données personnalisé évalué par autoexp.dat.
Les procédures suivantes décrivent ces étapes en détail.
Pour générer la DLL du complément Évaluateur d'expression
Dans Visual Studio, ouvrez la solution eeaddin.sln.
Dans le menu Générer, cliquez sur Générer.
Copiez le fichier eeaddin.dll obtenu dans votre répertoire common7\ide (le répertoire qui contient devenv.exe).
Dans le menu Fichier, cliquez sur Fermer la solution.
Pour modifier autoexp.dat
Dans le menu Fichier, pointez sur Ouvrir, puis cliquez sur Fichier.
Dans la boîte de dialogue Ouvrir un fichier, recherchez le fichier autoexp.dat (dans le répertoire common7\packages\debugger) et cliquez sur Ouvrir.
Ajoutez les lignes suivantes à autoexp.dat :
_SYSTEMTIME=$ADDIN(eeaddin.dll,AddIn_SystemTime@28) _FILETIME=$ADDIN(eeaddin.dll,AddIn_FileTime@28)
Enregistrez autoexp.dat.
Pour créer un projet qui utilise les types de données personnalisés
Dans le menu Fichier, pointez sur New, puis cliquez sur Projet.
Dans la boîte de dialogue Nouveau projet, mettez Projets Visual C++ en surbrillance, cliquez sur Application MFC, entrez un nom pour le projet et cliquez sur OK.
Dans l'Assistant Application MFC, cliquez sur Terminer. Le projet doit être une application MFC, car au cours de l'étape suivante, vous allez ajouter des fonctions MFC.
Dans l'application MFC, ajoutez un objet SYSTEMTIME ou FILETIME.
SYSTEMTIME *s = new SYSTEMTIME(); FILETIME *f = new FILETIME(); GetSystemTime(s); SystemTimeToFileTime(s,f);
Dans le menu Générer, cliquez sur Générer.
Commencez le débogage et observez vos objets SYSTEMTIME ou FILETIME dans la fenêtre Espion.
Fonctionnement de l'exemple
Pour étendre l'évaluateur d'expression à un type de données personnalisé, écrivez une fonction de visionneuse personnalisée dans la DLL du complément Évaluateur d'expression. Cette fonction utilise un pointeur vers un objet situé dans l'espace mémoire du programme en cours de débogage (et non dans l'espace mémoire de l'évaluateur d'expression que vous étendez). Vous ne pouvez pas utiliser les casts normaux avec ce pointeur. Vous devez lire le pointeur et les données vers lesquelles il pointe à l'aide d'une fonction de rappel. Un pointeur de rappel du type DEBUGHELPER* pointe vers un objet selon diverses méthodes.
Voici un exemple de la syntaxe utilisée :
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
)
L'exemple comporte deux implémentations de ce type de fonction, AddIn_SystemTime et AddIn_FileTime dans timeaddin.cpp. Le struct DEBUGHELPER (défini dans custview.h) est composé de pointeurs fonction pouvant vous aider à écrire votre extension. Ce pointeur est passé à votre fonction CustomViewer et vous pouvez l'utiliser pour appeler les fonctions d'assistance.
Vous pouvez obtenir le type du processeur avec pHelper->GetProcessorType. Deux méthodes permettent de lire la mémoire, pHelper->ReadDebuggeeMemory et pHelper->ReadDebuggeeMemoryEx. ReadDebuggeeMemoryEx gère les adresses 64 bits et est pris en charge par le débogueur de Visual Studio .NET. ReadDebuggeeMemory ne gère pas les adresses 64 bits et est pris en charge par les débogueurs Visual Studio .NET et Visual C++ 6.0. Si votre complément est conçu pour le débogueur Visual Studio .NET uniquement, vous pouvez utiliser ReadDebuggeeMemoryEx. Si votre complément doit également fonctionner avec Visual C++ 6.0, vous devez vérifier le champ dwVersion et éviter d'appeler ReadDebuggeeMemoryEx pour Visual C++ 6.0.
Le code suivant fonctionne avec les deux débogueurs et lit le contenu d'un localobject (dont le type est MyType) à partir du programme en cours de débogage :
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
Modification d'autoexp.dat
Dans la section [AutoExpand] d'autoexp.dat, les lignes que vous ajoutez présentent la syntaxe suivante :
type=$ADDIN(dllname.dll,exportname)
Par exemple :
_SYSTEMTIME=$ADDIN(eeaddin.dll,AddIn_SystemTime)
ou :
_FILETIME=$ADDIN(eeaddin.dll,AddIn_FileTime)
Si la DLL ne se trouve pas dans le répertoire contenant devenv.exe ou dans PATH, vous devez utiliser un chemin d'accès complet pour la DLL. L'argument exportname respecte la casse et doit correspondre exactement au nom exporté que vous avez obtenu en exécutant dumpbin –exports sur votre DLL.
Pour tester le débogueur avec le nouveau complément, arrêtez tout d'abord tout débogage en cours au moment de l'installation de la nouvelle DLL, puis démarrez une nouvelle session du débogueur.
Remarque Le complément s'exécute dans le débogueur, tout incident dans votre code entraîne la panne de l'IDE.