Visual Studio natvis 显示指向接口的指针

Posted

技术标签:

【中文标题】Visual Studio natvis 显示指向接口的指针【英文标题】:Visual Studio natvis displaying pointer-to-interface 【发布时间】:2017-05-30 14:24:12 【问题描述】:

我正在尝试为我们公司的自定义智能指针创建调试可视化工具。我想使用ExpandItem 将内容仅向下一层,这适用于ref_ptr<Vector2d> 之类的具体类型,但不适用于ref_ptr<IStreamManager> 之类的虚拟类型。使用虚拟类型时,我得到两个条目,一个用于基础类型,然后我可以扩展它,另一个用于__vfptr

我得到了什么:

v streamManagerPtr         shared_ptr  count=35, ptr=... 
    [Reference Count]      2
  v [StreamMgr]            ...
      m_resourceMgr        shared_ptr  count=35, ptr=... 
      m_fileMgr            shared_ptr  count=23, ptr=... 
      ...
  > __vfptr                0xdeadbeef
  > [Raw View]             ...

我想要什么:

v streamManagerPtr         shared_ptr  count=35, ptr=... 
    [Reference Count]      2
    m_resourceMgr          shared_ptr  count=35, ptr=... 
    m_fileMgr              shared_ptr  count=23, ptr=... 
    ...
  > [Raw View]             ...

有什么方法可以将底层动态类型的内容再上一层,这样我就不必处理这种无用的嵌套级别了?

【问题讨论】:

【参考方案1】:

我相信你可以使用这样的东西:

<Type Name="shared_ptr&lt;*&gt;">
  <Expand>
    <ExpandedItem Condition="ptr != 0">*ptr</ExpandedItem>
  </Expand>
</Type>

ExpandedItem 标签基本上移除了嵌套级别,显示标签中项目的内容,就好像它们是与Expand 标签中的其余Items 相同的嵌套级别的常规项目一样.

【讨论】:

ref_ptr 不是std::shared_ptr,所以这不会有效果。【参考方案2】:

我没有使用ref_ptr,所以我使用自己的模板类进行了测试。因此,如果以下代码可能无法立即与 ref_ptr 一起使用,请多多包涵。

<Type Name="ref_ptr&lt;*&gt;" Priority="MediumLow">
  <Expand>
    <ExpandedItem Condition="_ptr->__vfptr">*_ptr</ExpandedItem>
  </Expand>
</Type>
<Type Name="ref_ptr&lt;*&gt;">
  <Expand>
    <ExpandedItem>_ptr</ExpandedItem>
  </Expand>
</Type>

在MSDN 上描述了这个技巧:natvis 尝试解析第一个条目。那是检查_ptr-&gt;__vfptr 是否不是nullptr。对于您的IStreamManager,这可以被解析并评估为真,因此使用第一个条目,对象本身被获取并扩展。如果第一个条目的条件由于没有__vfptr 而无法解析,则不使用第一个条目并使用第二个条目。那就是你现在在现有代码中所做的事情。

【讨论】:

以上是关于Visual Studio natvis 显示指向接口的指针的主要内容,如果未能解决你的问题,请参考以下文章

为 JsonCpp 寻找 Visual Studio 可视化工具(natvis)

Visual Studio natvis 语句的局部变量

访问 Visual Studio ImageWatch 插件的 .natvis 文件中的矢量基础数据

在Visual Studio 2013中是否有用于调试Qt 4.8项目的非官方可视化工具?

Visual Studio 2019 UTF-8编码调试显示中文

在 Visual Studio 2015 调试器中查看 Qt5.6 QStrings