gpt4 book ai didi

c++ - 如何为 Visual Studio 2012 调试器编写自定义 native 可视化工具 DLL?

转载 作者:IT老高 更新时间:2023-10-28 21:45:47 26 4
gpt4 key购买 nike

在 C++ 中为 Visual Studio 2012 调试器编写自定义 native 可视化 DLL 需要什么?我想显示一个只能按需从类/结构计算的值,因此需要 native 可视化 DLL。 Visual Studio 2012 使用一种新方法来实现称为 Natvis 的 native 可视化工具。截至目前,关于 Natvis 的正确信息非常少,尤其是关于使用 Natvis 调用可视化 DLL 的信息。 DLL 将根据类/结构成员值计算显示字符串。

最佳答案

这是构成插件 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 包含两个可视化方法调用; MyClassFormatter 格式化 MyClass 和 MyStructFormatter 格式化 MyStruct。对于指定类型(MyClass、MyStruct)的每个实例,调试器将在 Auto、Watch 或工具提示显示中显示方法的格式化值。

<?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:

[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\11.0_Config\Debugger]

"EnableNatvisDiagnostics"=dword:00000001

如果一切顺利,您将看到 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;
}

信息资源:

\Xml\Schemas\natvis.xsd

http://code.msdn.microsoft.com/windowsdesktop/Writing-type-visualizers-2eae77a2

http://blogs.msdn.com/b/mgoldin/archive/2012/06/06/visual-studio-2012-and-debugger-natvis-files-what-can-i-do-with-them.aspx

http://blogs.msdn.com/b/vcblog/archive/2012/07/12/10329460.aspx

关于c++ - 如何为 Visual Studio 2012 调试器编写自定义 native 可视化工具 DLL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11545418/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com