Ejemplo EEAddIn: complemento del evaluador de expresiones de depuración

El ejemplo EEAddin muestra la forma de ampliar el evaluador de expresiones nativo del depurador mediante la API del complemento Evaluador de expresiones.

Nota de seguridadNota sobre la seguridad

En este ejemplo de código se ilustra un concepto y únicamente se muestra el código correspondiente a dicho concepto. Es posible que no cumpla los requisitos de seguridad de un entorno concreto y, por tanto, no debería utilizarse tal y como se muestra. Se recomienda agregar código de seguridad y de control de errores para que los proyectos sean más seguros y sólidos. Microsoft proporciona este ejemplo "tal cual" sin ninguna garantía.

Para obtener ejemplos e instrucciones para su instalación:

Para obtener acceso a los ejemplos de Visual Studio

  • En el menú Ayuda, haga clic en Ejemplos.

    De forma predeterminada, los ejemplos se instalan en unidad:\Archivos de programa\Microsoft Visual Studio 10.0\Samples\.

  • Para obtener la versión más reciente de este ejemplo, así como una lista de otros ejemplos, vea Visual Studio Samples en el sitio web de MSDN.

API del complemento Evaluador de expresiones

El evaluador de expresiones forma parte del depurador que interpreta (evalúa) expresiones. Cuando establezca un punto de interrupción en una expresión o escriba una expresión en una ventana de depuración, el evaluador de expresiones interpretará el resultado. Para obtener información detallada, vea Expresiones en el depurador. Con la API del complemento Evaluador de expresiones puede ampliar el evaluador de expresiones para controlar tipos nuevos.

Si desea ampliar el evaluador de expresiones para un tipo nuevo, debe escribir una función como parte de un archivo DLL de Win32 (en el mismo directorio que autoexp.dat) y exportarla por nombre. También tiene que agregar una línea al archivo autoexp.dat. Puede ampliar el evaluador de expresiones para más de un tipo exportando varias funciones del archivo DLL.

Generar y ejecutar el ejemplo

Los pasos necesarios para generar y ejecutar este ejemplo se dividen en tres partes:

Para generar y ejecutar este ejemplo

  1. Genere un archivo DLL del complemento evaluador de expresiones (eeaddin.dll).

  2. Edite autoexp.dat para utilizar el archivo DLL del complemento evaluador de expresiones.

  3. Pruebe el complemento; para ello, cree un proyecto que utilice el tipo de datos personalizado evaluado por autoexp.dat.

Los siguientes procedimientos describen estos métodos con detalle.

Para generar el archivo DLL del complemento evaluador de expresiones

  1. En Visual Studio, abra la solución eeaddin.sln.

  2. En el menú Generar, haga clic en Generar.

  3. Copie el archivo eeaddin.dll resultante al directorio common7\ide (el mismo directorio que contiene devenv.exe).

  4. En el menú Archivo, haga clic en Cerrar solución.

Para editar autoexp.dat

  1. En el menú Archivo, seleccione Abrir y haga clic en Archivo.

  2. En el cuadro de diálogo Abrir archivo, busque el archivo autoexp.dat (en el directorio common7\packages\debugger) y haga clic en Abrir.

  3. Edite autoexp.dat para agregar las líneas siguientes:

    _SYSTEMTIME=$ADDIN(eeaddin.dll,AddIn_SystemTime@28)
    _FILETIME=$ADDIN(eeaddin.dll,AddIn_FileTime@28)
    

    Guarde autoexp.dat.

Para crear un proyecto que utilice los tipos de datos personalizados

  1. En el menú Archivo, seleccione New y haga clic en Proyecto.

  2. En el cuadro de diálogo Nuevo proyecto, resalte Proyectos de Visual C++, haga clic en Aplicación MFC, escriba un nombre para el proyecto y haga clic en Aceptar.

  3. En el Asistente para aplicaciones MFC, haga clic en Finalizar. El proyecto debe ser una aplicación MFC, ya que en el paso siguiente agregará funciones MFC.

  4. En la aplicación MFC, agregue un objeto SYSTEMTIME o FILETIME.

    SYSTEMTIME *s = new SYSTEMTIME();
    FILETIME *f = new FILETIME();
    GetSystemTime(s);
    SystemTimeToFileTime(s,f);
    
  5. En el menú Generar, haga clic en Generar.

  6. Inicie la depuración y examine los objetos SYSTEMTIME o FILETIME en la ventana Inspección.

Cómo funciona el ejemplo

Si desea ampliar el evaluador de expresiones para un tipo de datos personalizado, debe escribir una función de visor personalizada en el archivo DLL del complemento evaluador de expresiones. La función utiliza un puntero a un objeto en el espacio de memoria del programa que se está depurando (no en el espacio de memoria del evaluador de expresiones que está ampliando). No puede utilizar conversiones normales con este puntero. Debe leer el puntero y los datos a los que apunta para utilizar una función de devolución de llamada. Un puntero de devolución de llamada del tipo DEBUGHELPER* apunta a un objeto con varios métodos.

La sintaxis tiene el siguiente aspecto:

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
)

El ejemplo tiene dos implementaciones de este tipo de función, AddIn_SystemTime y AddIn_FileTime en timeaddin.cpp. El struct DEBUGHELPER (definido en custview.h) consta de punteros a función que le ayudan a escribir la extensión. Este puntero se pasa a la función CustomViewer y puede utilizarlo para llamar a las funciones auxiliares.

Puede obtener el tipo de procesador con pHelper->GetProcessorType. Existen dos métodos para leer la memoria, pHelper->ReadDebuggeeMemory y pHelper->ReadDebuggeeMemoryEx. ReadDebuggeeMemoryEx controla direcciones de 64 bits y lo admite el depurador de Visual Studio .NET. ReadDebuggeeMemory no controla direcciones de 64 bits y lo admiten los depuradores de Visual Studio .NET y Visual C++ 6.0. Si el complemento sólo está diseñado para el depurador de Visual Studio .NET, puede utilizar ReadDebuggeeMemoryEx. Si el complemento también tiene que funcionar con Visual C++ 6.0, debe comprobar el campo dwVersion y evitar llamar a ReadDebuggeeMemoryEx para Visual C++ 6.0.

El siguiente fragmento de código funciona con los dos depuradores y lee el contenido de un objeto local, localobject (que tiene el tipo MyType), del programa que se está depurando:

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

Editar autoexp.dat

En la sección [AutoExpand] de autoexp.dat, las líneas que agregue tendrán la siguiente sintaxis:

type=$ADDIN(dllname.dll,exportname)

Por ejemplo:

_SYSTEMTIME=$ADDIN(eeaddin.dll,AddIn_SystemTime)

O bien

_FILETIME=$ADDIN(eeaddin.dll,AddIn_FileTime)

Si el archivo DLL no está en el directorio que contiene devenv.exe o no está en la ruta (PATH), debe utilizar el nombre completo del archivo DLL, con la ruta. El argumento exportname distingue entre mayúsculas y minúsculas y debe coincidir exactamente con el nombre exportado que recibió al ejecutar dumpbin –exports en el archivo DLL.

Para probar el depurador con el nuevo complemento, detenga primero la depuración del programa que estuviera depurando al instalar el nuevo archivo DLL y, a continuación, inicie una nueva sesión de depurador.

Nota El complemento se ejecuta en el depurador; por tanto, si el código provoca un bloqueo, se bloqueará el IDE.

Vea también

Otros recursos

Ejemplos generales