¿Qué se necesita para escribir una DLL de visualizador nativa personalizada en C++ para Visual Studio 2012 depurador? Quiero mostrar un valor que solo se puede calcular a partir de una clase/estructura bajo demanda, por lo tanto, se requiere una DLL del visualizador nativo. Visual Studio 2012 usa un nuevo método para implementar visualizadores nativos llamado Natvis. A partir de este momento, hay muy poca información correcta sobre Natvis y especialmente sobre el uso de Natvis para llamar a un visualizador DLL. La DLL calculará una cadena de visualización basada en los valores de los miembros de clase/estructura.Cómo escribir una DLL de visualizador nativa personalizada para Visual Studio 2012 depurador?
Respuesta
Aquí está el código de C++ que comprende AddIn DLL. Llamé al archivo NatvisAddIn.cpp y el proyecto creó NatvisAddIn.dll.
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#define ADDIN_API __declspec(dllexport)
typedef struct tagDEBUGHELPER
{
DWORD dwVersion;
HRESULT (WINAPI *ReadDebuggeeMemory)(struct tagDEBUGHELPER *pThis, DWORD dwAddr, DWORD nWant, VOID* pWhere, DWORD *nGot);
// from here only when dwVersion >= 0x20000
DWORDLONG (WINAPI *GetRealAddress)(struct tagDEBUGHELPER *pThis);
HRESULT (WINAPI *ReadDebuggeeMemoryEx)(struct tagDEBUGHELPER *pThis, DWORDLONG qwAddr, DWORD nWant, VOID* pWhere, DWORD *nGot);
int (WINAPI *GetProcessorType)(struct tagDEBUGHELPER *pThis);
} DEBUGHELPER;
typedef HRESULT (WINAPI *CUSTOMVIEWER)(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved);
extern "C" ADDIN_API HRESULT MyClassFormatter(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved);
extern "C" ADDIN_API HRESULT MyStructFormatter(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved);
class MyClass
{
public:
int publicInt;
};
struct MyStruct { int i; };
ADDIN_API HRESULT MyClassFormatter(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved)
{
MyClass c;
DWORD nGot;
pHelper->ReadDebuggeeMemory(pHelper,dwAddress,sizeof(MyClass),&c,&nGot);
sprintf_s(pResult,max,"Dll MyClass: max=%d nGot=%d MyClass=%x publicInt=%d",max,nGot,dwAddress,c.publicInt);
return S_OK;
}
ADDIN_API HRESULT MyStructFormatter(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved)
{
MyStruct s;
DWORD nGot;
pHelper->ReadDebuggeeMemory(pHelper,dwAddress,sizeof(MyStruct),&s,&nGot);
sprintf_s(pResult,max,"Dll MyStruct: max=%d nGot=%d MyStruct=%x i=%d",max,nGot,dwAddress,s.i);
return S_OK;
}
Aquí está el archivo .natvis el que Visual Studio 2012 depurador utiliza para visualizar el valor. Colóquelo en un archivo .natvis. Lo llamé NatvisAddIn.natvis. El archivo indica al depurador de VS 2012 que llame a NatvisAddIn.dll. El dll contiene dos llamadas al método visualizador; MyClassFormatter para formatear MyClass y MyStructFormatter para formatear MyStruct. El depurador mostrará el valor formateado del método en la pantalla Auto, Watch o Tooltip para cada instancia del tipo especificado (MyClass, MyStruct).
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="MyClass">
<DisplayString LegacyAddin="NatvisAddIn.dll" Export="MyClassFormatter"></DisplayString>
</Type>
<Type Name="MyStruct">
<DisplayString LegacyAddin="NatvisAddIn.dll" Export="MyStructFormatter"></DisplayString>
</Type>
</AutoVisualizer>
Place tanto el archivo NatvisAddIn.dll compilado y los archivos NatvisAddIn.natvis en una de las tres ubicaciones siguientes:
%VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers (requires admin access)
%USERPROFILE%\My Documents\Visual Studio 2012\Visualizers\
VS extension folders
Usted tendrá que asegurarse de que existe la siguiente clave del Registro y el valor es 1:
[HKEY_CURRENT_USER \ Software \ Microsoft \ VisualStudio \ 11.0_Config \ depurador]
"EnableNatvisDiagnostics" = dword: 00000001
Si todo va bien, se pueden ver natvis mensajes aparecen en la ventana de salida del depurador de Visual Studio. Los mensajes mostrarán si Natvis fue capaz de analizar los archivos .natvis. Los resultados de analizar cada archivo .natvis se muestran en la ventana de resultados. Si algo está mal, use el comando "dumpbin/exports" para verificar que los nombres de los métodos DLL coincidan exactamente con el tipo de archivo .navis =. Asegúrese también de que los archivos .dll y .natvis actuales se hayan copiado en el directorio apropiado.
Natvis: Parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\atlmfc.natvis.
Natvis: Done parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\atlmfc.natvis.
Natvis: Parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\concurrency.natvis.
Natvis: Done parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\concurrency.natvis.
Natvis: Parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\NatvisAddIn.natvis.
Natvis: Done parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\NatvisAddIn.natvis.
Natvis: Parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\stl.natvis.
Natvis: Done parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\stl.natvis.
Natvis: Parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\windows.natvis.
Natvis: Done parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\windows.natvis.
Natvis: Parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\winrt.natvis.
Natvis: Done parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\winrt.natvis.
Programa de prueba:
#include "stdafx.h"
#include <iostream>
class MyClass
{
public:
int publicInt;
};
struct MyStruct { int i; };
int _tmain(int argc, _TCHAR* argv[])
{
struct MyStruct s = {1234};
std::cout << s.i << std::endl;
MyClass *c = new MyClass;
c->publicInt = 1234;
std::cout << c->publicInt << std::endl;
return 0;
}
recursos de información:
\ XML \ schemas \ natvis.xsd
http://code.msdn.microsoft.com/windowsdesktop/Writing-type-visualizers-2eae77a2
http://blogs.msdn.com/b/vcblog/archive/2012/07/12/10329460.aspx
¿por qué esto se revocó? –
Gracias por preguntar Hubo un par de votos negativos posiblemente porque no había rellenado todos los talones. Estaba agregando en tiempo real. Aprendí que debería completar la publicación en la publicación inicial, si es posible. La publicación ahora está completa, por lo que debería haber un montón de upvotes acumulando. – BSalita
Primero, gracias por publicarlo, pero no creo que esto funcione para las aplicaciones de 64 bits. (DWORD se usa para la dirección, por ejemplo, y otras cosas). Además, ¿cómo podría uno hacer un complemento que de alguna manera se ocupe del código de 32 bits/64 bits del otro lado? – malkia
Para la versión de 64 bits de depuración, líneas siguientes deben utilizarse:
auto realAddress = pHelper->GetRealAddress(pHelper);
pHelper->ReadDebuggeeMemoryEx(pHelper, realAddress, sizeof(MyClass), &c, &nGot);
Por ejemplo anterior, la versión de 64 bits podría parecer esto:
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#define ADDIN_API __declspec(dllexport)
typedef struct tagDEBUGHELPER
{
DWORD dwVersion;
HRESULT (WINAPI *ReadDebuggeeMemory)(struct tagDEBUGHELPER *pThis, DWORD dwAddr, DWORD nWant, VOID* pWhere, DWORD *nGot);
// from here only when dwVersion >= 0x20000
DWORDLONG (WINAPI *GetRealAddress)(struct tagDEBUGHELPER *pThis);
HRESULT (WINAPI *ReadDebuggeeMemoryEx)(struct tagDEBUGHELPER *pThis, DWORDLONG qwAddr, DWORD nWant, VOID* pWhere, DWORD *nGot);
int (WINAPI *GetProcessorType)(struct tagDEBUGHELPER *pThis);
} DEBUGHELPER;
typedef HRESULT (WINAPI *CUSTOMVIEWER)(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved);
extern "C" ADDIN_API HRESULT MyClassFormatter(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved);
class MyClass
{
public:
int publicInt;
};
ADDIN_API HRESULT MyClassFormatter(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved)
{
MyClass c;
DWORD nGot;
auto realAddress = pHelper->GetRealAddress(pHelper);
pHelper->ReadDebuggeeMemoryEx(pHelper, realAddress, sizeof(MyClass), &c, &nGot);
sprintf_s(pResult,max,"Dll MyClass: max=%d nGot=%d MyClass=%llx publicInt=%d",max, nGot, realAddress, c.publicInt);
return S_OK;
}
- 1. visualizador de depurador de Visual C++?
- 2. ¿Hay un visualizador de depurador de Visual Studio para la sesión de ASP.NET?
- 3. EnvDTE sustituto en Visual Studio 2012
- 4. Visual Studio 2012 en comparación con Visual Studio 2010 (delta)
- 5. Productivity Power Tools para Visual Studio 2012
- 6. Visual Studio 2012 Network Shares
- 7. Invocar una publicación de msbuild para visual studio 2012
- 8. Visual Studio 2012 marcos faltantes
- 9. Visual Studio 2012 Conditional Bundling
- 10. Visual Studio no está cargando mi visualizador de depuración
- 11. ¿Cómo agregar comandos a Visual Studio 2012?
- 12. PowerCommands for Visual Studio 2012?
- 13. Limitaciones de Visual Studio 2012 Express Desktop
- 14. Visual Studio: DLL diferentes para configuraciones
- 15. ¿Cómo implementar una herramienta personalizada de Visual Studio?
- 16. Debugging XAML databinding en Visual Studio 2012
- 17. ¿Existe un Visualizador de árbol de expresiones para VS 2012?
- 18. Publicación parcial de Visual Studio 2012
- 19. Depurador de Visual Studio 2010 omitiendo
- 20. Contraer html en Visual Studio 2012
- 21. Políticas personalizadas en Visual Studio 2012 y TFS 2010
- 22. Mercurial .hgignore para proyectos de Visual Studio 2012
- 23. ReportViewer 11 (2012) Visual Studio 2010
- 24. Visual Studio 2012 + Business Intelligence Plantillas
- 25. Private Accessors en Visual Studio 2012
- 26. Visual Studio 2012 no crea proyectos dependientes
- 27. Visual Studio 2012 no puede crear proyecto
- 28. Visual Studio 2010 no puede abrir una solución de 2010 que Visual Studio 2012 modificó
- 29. Desarrollo para .NET 4.0 (Windows XP) con Visual Studio 2012
- 30. ¿dónde está _mm_prefetch en Visual Studio 2012?
http://code.msdn.microsoft.com/windowsdesktop/Writing-type-visualizers-2eae77a2 –
Eso es un gran post natvis, que también he mencionado más adelante, pero no tiene una palabra acerca de la escritura un visualizador nativo personalizado dll. Seré generoso y diré que es muy temprano en el juego para que Microsoft cubra todo el tema. – BSalita