[VS2015] Natvis: inspect vector data in custom visualiser

Started by
3 comments, last by Juliean 8 years ago

Hello,

I'm using custom memory management using a vector<char> for my components in a template-class. With how its used, this vecto data is equal to:


template<typename ComponentType>
class ComponentPool
{
    std::vector<char> m_vComponents;

    void Test()
    {
        auto pComponents = (ComponentType*)vComponents.data();

        for(size_t i = 0; i < vComponent.size() / sizeof(ComponentType); i++)
        {
        }
    }
}

Just so you get the idea. Now I want to write a visualiser that allows me to view that content of the vector as an array of ComponentType, as shown in the Test()-function.

So since you cannot call functions in natvis, I have to access the vector data directly. Looking at how vector is implemented in natvis:


  <Type Name="std::vector&lt;*&gt;" Priority="MediumLow">
      <DisplayString>{{ size={_Mylast - _Myfirst} }}</DisplayString>
      <Expand>
          <Item Name="[capacity]" ExcludeView="simple">_Myend - _Myfirst</Item>
          <ArrayItems>
              <Size>_Mylast - _Myfirst</Size>
              <ValuePointer>_Myfirst</ValuePointer>
          </ArrayItems>
      </Expand>
  </Type>

It seems you have to use _Myfirst. However, when I do it:


    <Type Name="acl::ecs::ComponentPool&lt;*&gt;">
        <Expand>
            <Item Name="Components">m_vComponents._Myfirst</Item>
        </Expand>
    </Type>

I get an error message:


D:\Acclimate\Repo\acclimate.natvis(42,28): Fehler: Ein Zeiger auf eine gebundene Funktion darf nur zum Aufrufen der Funktion verwendet werden.

(roughly translates to) Error: A pointer to a bound function can only be used to call the function

That error btw. is in the line where I access _Myfirst. Now I see that in c++ _Myfirst is actually called (_Myfirst()), but I wonder why it works in the stl-natvis and not here.

Anyone any idea on why this doesn't work, or any solution? (I could just screw std::vector<char> and use a char*, but thats making the code more complicated and unsafe).

Thanks!

Advertisement

Not sure about your issue but you can "inherit" the expanded vector with


<Expand>
    <ExpandedItem>m_vComponents</ExpandedItem>
</Expand>

Thanks for the suggestion,
I know I can do that, but the problem is that m_vComponents is of type char, and I want to view it as "ComponentType"-template type.
I think a hackfix could be to store an additional pointer variable of type ComponentType* and assign m_vComponents.data() to is, but I'd really prefer not to make modifications to my code in order to do this.

Your getting into implementation details of std::vector by using _Myfirst. That kind of code isn't portable. Why can't you just call m_vComponents.data()? as in:


<Item Name="Components">m_vComponents.data()</Item>

Of course I'm not familiar with how natvis works, and there are peculiarities related to it.

Your getting into implementation details of std::vector by using _Myfirst. That kind of code isn't portable. Why can't you just call m_vComponents.data()? as in:


<Item Name="Components">m_vComponents.data()</Item>

Of course I'm not familiar with how natvis works, and there are peculiarities related to it.

I'd love too and trust me, this would make some other natvis-code much easier, but unfortunately you cannot call any kind of function in natvis (similar to breakpoint-conditions & debug-watch) because of possible side-effects (tried it, gives an error message).

Portability should be only half-bad though, since natvis is only used by VS2013+ anyways, and I make a conditional display based on some version-define anyways if I want to. Problem is just that it cannot be done that way :(

This topic is closed to new replies.

Advertisement