在C++中为Visual Studio 2012调试器编写自定义 native 可视化程序DLL需要什么?我想显示一个只能按需从类/结构计算的值,因此需要 native 可视化程序DLL。 Visual Studio 2012使用一种称为Natvis的新方法来实现 native 可视化工具。到目前为止,有关Natvis的信息很少,尤其是有关使用Natvis调用可视化程序DLL的正确信息。 DLL将基于类/结构成员值计算显示字符串。
最佳答案
这是组成AddIn DLL的C++代码。我将文件命名为NatvisAddIn.cpp,然后该项目创建了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;
}
这是Visual Studio 2012调试器用来显示值的.natvis文件。将其放在.natvis文件中。我将其命名为NatvisAddIn.natvis。该文件指示VS 2012调试器调用NatvisAddIn.dll。该dll包含两个Visualizer方法调用; MyClassFormatter用于格式化MyClass,而MyStructFormatter用于格式化MyStruct。调试器将在“自动”,“监视”或工具提示显示中为指定类型的每个实例(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>
将已编译的NatvisAddIn.dll文件和NatvisAddIn.natvis文件都放入以下三个位置之一:
%VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers (requires admin access)
%USERPROFILE%\My Documents\Visual Studio 2012\Visualizers\
VS extension folders
您将需要确保以下注册表项存在,并且值为1:
如果一切顺利,您将看到natvis消息出现在Visual Studio的调试器“输出”窗口中。该消息将显示Natvis是否能够解析.natvis文件。解析每个.natvis文件的结果将显示在输出窗口中。如果出现问题,请使用命令“dumpbin/exports”仔细检查DLL方法的名称是否与.navis文件的Type =完全匹配。还要确保将当前的.dll和.natvis文件复制到适当的目录中。
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.
测试程序:
#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;
}
信息资源:
关于c++ - 如何为Visual Studio 2012调试器编写自定义 native 可视化程序DLL?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11545418/