vs natvis编写,自定义vs中变量的展示

vs 自定义变量的显示规则

1. 自定义结构体或者类在vs变量窗口显示带来的问题

struct Marray
{
    int *data;
    int length;
};

首先定义一个数组结构体,data指向一块内存,length是这个数组的大小

然后编写如下代码

#include <stdio.h>
#include <stdlib.h>

#define ARRAYSIZE	3

struct Marray
{
    int *data;
    int length;
};

int main(int argc, char* argv[])
{
	struct Marray arr;
	arr.data = (int*)malloc(sizeof(int) * ARRAYSIZE);
	arr.length = ARRAYSIZE;

	arr.data[0] = 1;
	arr.data[1] = 2;
	arr.data[2] = 3;

	printf("hello word\n");

	return 0;
}

在vs中arr这个变量会如何显示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-atz1XAs0-1656169374282)(./1.png)]

但是我们实际上想让他把data的三个元素都显示出来,这样子便于调试发现问题

vs给我们提供了自定显示规则的方法,编写vs支持的xml文件,官方叫做natvis文件
这个文件有两种添加方式:

  • 一种是直接放在vs的安装目录 %VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers
  • 一种是在项目中添加
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hkdUcvrD-1656169374283)(./2.png)]

也就是一种是全局的,一个是只生效这个项目中的

2. natvis文件的编写

natvis文件是xml格式文件,遵循xml语法。

2.1 xml的转义字符

&lt;	<	小于
&gt;	>	大于
&amp;	&	和号
&apos;	'	单引号
&quot;	"	双引号

如果在编写时用到这些符号需要转义

2.2 natvis语法

2.2.1 声明部分
<?xml version="1.0" encoding="utf-8"?> 
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">

</AutoVisualizer>

这三行固定这么写就行。第一行是xml文件的声明,第二行的vs命名空间的声明

2.2.2 类型指定

Type 标签是用来指定需要可视化类型的标签,他有一个属性是Name用来指定要自定义可视化的类型

如要指定我们刚才的Marray类型

<?xml version="1.0" encoding="utf-8"?> 
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
	<Type Name="Marray">

	</Type>
</AutoVisualizer>
2.2.3 顶级可视化显示

DisplayString标签是用来显示变量标签用的。
如遇到 Marray 我就让vs显示 hello array

<?xml version="1.0" encoding="utf-8"?> 
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
	<Type Name="Marray">
		<DisplayString>hello array</DisplayString>
	</Type>
</AutoVisualizer>

vs中的展示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1SSxxuVW-1656169374284)(./4.png)]

DisplayString 可以显示这个结构体成员的值 只需要在成员变量上加上 '{}'就可以转义

<?xml version="1.0" encoding="utf-8"?> 
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
	<Type Name="Marray">
		<DisplayString>size={length}</DisplayString>
	</Type>
</AutoVisualizer>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3m6uep5H-1656169374284)(./5.png)]

2.2.3 类型展开

Expand 是用来做类型展开的标记

Item 是Expand的子标记可以用来展示一个项

<?xml version="1.0" encoding="utf-8"?> 
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
	<Type Name="Marray">
		<DisplayString>size={length}</DisplayString>
		<Expand>
			<Item Name="[size]">length</Item>
			<Item Name="test">"hello"</Item>
		</Expand>
	</Type>
</AutoVisualizer>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8wmc8JGN-1656169374285)(./6.png)]

可以看到Item标签的Name属性是展开项的名称,item的值不能像DisplayString可以用{}展开变量,item标签只能显示一个值,这个值可以是成员变量(这个不能加{})

2.2.3.1 连续内存的展开

ArrayItems是连续内存的列表展开,只需要内存的指针和数组大小就行
这个标记很适合现在的Marray结构的展开

<?xml version="1.0" encoding="utf-8"?> 
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
	<Type Name="Marray">
		<DisplayString>{{ size={length} }}</DisplayString>
		<Expand>
			<Item Name="[size]">length</Item>
			<ArrayItems>
				<Size>length</Size>
				<ValuePointer>data</ValuePointer>
			</ArrayItems>
		</Expand>
	</Type>
	
</AutoVisualizer>

ValuePointer标签是填内存的值
size是数组的大小

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D9GIr7L6-1656169374285)(./3.png)]

2.2.3.2 程序展开

CustomListItems 是可执行程序的展开的标签
Exec 标签可以执行程序
Loop 循环
Break 跳出循环
Variable 定义变量
Condition 属性是条件属性

<?xml version="1.0" encoding="utf-8"?> 
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
	<Type Name="Marray">
		<DisplayString>{{ size={length} }}</DisplayString>
		<Expand>
			<CustomListItems>
				<Variable Name="i" InitialValue="0"/>
				<Loop>
					<Break Condition="i &gt;= length"/>
					<Item Name="[{i}]">data[i]</Item>
					<Exec>i = i + 1</Exec>
				</Loop>
			</CustomListItems>
		</Expand>
	</Type>
</AutoVisualizer>
2.2.4 自定义展开子元素

可以创建人工子元素,这个标签要在标签中使用

我们定义一些测试结构

#define ARRAYSIZE	3

struct Marray
{
    int *data;
    int length;
};

struct MStruct
{
	int test;
	struct Marray _arr1;
	struct Marray _arr2;
};

我们需要将MStruct结构展开

测试代码

int main(int argc, char* argv[])
{
	struct MStruct m;
	m._arr1.data = (int*)malloc(sizeof(int) * ARRAYSIZE);
	m._arr1.length = ARRAYSIZE;

	m._arr2.data = (int*)malloc(sizeof(int) * ARRAYSIZE);
	m._arr2.length = ARRAYSIZE;

	m._arr1.data[0] = 1;
	m._arr1.data[1] = 2;
	m._arr1.data[2] = 3;

	m._arr2.data[0] = 4;
	m._arr2.data[1] = 5;
	m._arr2.data[2] = 6;

	printf("hello word\n");

	return 0;
}

结构展开的编写

<?xml version="1.0" encoding="utf-8"?> 
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
	<Type Name="MStruct">
		<Expand>
			<Item Name="test">test</Item>
			<Synthetic Name="_arr1">
				<DisplayString>{{size = {_arr1.length}}}</DisplayString>
				<Expand>
					<Item Name="[size]">_arr1.length</Item>
					<ArrayItems>
						<Size>_arr1.length</Size>
						<ValuePointer>_arr1.data</ValuePointer>
					</ArrayItems>
				</Expand>
			</Synthetic>
			<Synthetic Name="_arr2">
				<DisplayString>{{size = {_arr2.length}}}</DisplayString>
				<Expand>
					<Item Name="[size]">_arr2.length</Item>
					<ArrayItems>
						<Size>_arr2.length</Size>
						<ValuePointer>_arr2.data</ValuePointer>
					</ArrayItems>
				</Expand>
			</Synthetic>
		</Expand>
	</Type>
</AutoVisualizer>

Synthetic 标签可以自定义自己的标签,对比item标签,Synthetic 标签可以有自己的DisplayString顶层视图和Expand的展开项。理论上使用这个可以无线递归子结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IQB3Sl8F-1656169374286)(./8.png)]

官方文档

https://docs.microsoft.com/zh-cn/visualstudio/debugger/create-custom-views-of-native-objects?view=vs-2022

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值