visual-studio-debuggingnatvis

Access to vector underlying data in .natvis files for Visual Studio ImageWatch plugin


The problem

Similar to this question, I am trying to use the ImageWatch plugin for my own defined type MyImageClass. ImageWatch is a Visual Studio Plugin that allows you to view Images in a graphical representation while debugging code. You can write .natvis files to add support for custom defined classes.

struct MyImageClass
{
  uint32_t width;
  uint32_t height;
  std::vector<char> image_data;
}

The ImageWatch plugin expects a char* type for the image data, however I am storing my data in a std::vector<char>. My .natvis file, is quite simple, (you can skip it, only for completeness)

<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> 
  <UIVisualizer ServiceId="{A452AFEA-3DF6-46BB-9177-C0B08F318025}" Id="1"
            MenuName="Add to Image Watch"/> 
  <Type Name="MyImageClass">
    <UIVisualizer ServiceId="{A452AFEA-3DF6-46BB-9177-C0B08F318025}" Id="1" />
  </Type>

  <Type Name="MyImageClass">
    <Expand>
      <Synthetic Name="[type]">
        <DisplayString>UINT8</DisplayString>
      </Synthetic>
      <Item Name="[channels]">1</Item>
      <Item Name="[width]">width</Item>
      <Item Name="[height]">height</Item>
      <Item Name="[planes]">1</Item>
      <Item Name="[data]">image_data</Item>
      <Item Name="[stride]">width</Item>
    </Expand>
  </Type>  
</AutoVisualizer>

But the following line I am struggeling with <Item Name="[data]">image_data</Item>. The image data assignment does not work, I cannot see the image in the viewer. Instead I get the message "invalid". Clearly, this is because image_data is a std::vector<char> and not char*.

What I have tried

I have tried many different things inside the <Item Name="[data]">image_data</Item> tag to access the vectors underlying char* data pointer, but none work:

What works, but isn't the ideal solution

As a workaround and to see if my data is correct I have added a char* to the struct and then assign it the vectors underlying data.

struct MyImageClass
{
  uint32_t width;
  uint32_t height;
  std::vector<char> image_data;
  char* image_data_ptr;
};

and then

image_data_ptr = image_data.data();

The .natvis file is changed accordingly

<Item Name="[data]">image_data_ptr</Item>

This works, and I can see the image in ImageWatch. However, I would hate to introduce an extra variable, only for the purpose of the VS debugger. Any help is highly appreciated.


Solution

  • So apparently the data of the vector can be analyzed the following way:

    <Item Name="[data]">image_data._Mypair._Myval2._Myfirst</Item>
    

    I found this out by analyzing the natvis debug output for a different vector.

    Edit:

    As I realized, this is implementation specific. The above solution works well under VS2015. In VS 2012, the solution which didn't work above

    <Item Name="[data]">image_data._Myfirst</Item>
    

    works quite well.