简体   繁体   中英

How to (temporarily) typecast CPtrList entries using natvis?

I'm working with a C++ solution, based on STL, and I'm using CPtrList collections.

I have here a CPtrList collection, containing void * entries, and I would like to typecast those automatically using a natvis file.

Currently, my natvis looks as follows:

<Type Name="CList&lt;*,*&gt;">
  <AlternativeType Name="CObList"></AlternativeType>
  <AlternativeType Name="CPtrList"></AlternativeType>
  <AlternativeType Name="CStringList"></AlternativeType>
  <AlternativeType Name="CTypedPtrList&lt;*,*&gt;"></AlternativeType>
  <DisplayString>{{iets anders Count = {m_nCount}}}</DisplayString>
  <Expand>
    <Item Name="Count">m_nCount</Item>
    <LinkedListItems>
      <Size>m_nCount</Size>
      <HeadPointer>m_pNodeHead</HeadPointer>
      <NextPointer>pNext</NextPointer>
      <ValueNode>data</ValueNode>
    </LinkedListItems>
  </Expand>
</Type>

As a result the entries of my CPtrList look like the following:

0x<something>      void *
0x<something else> void *
...

I would like to have the entries typecasted into something like this:

<information>      CElement::SL_SET_PARAMETER*
<information else> CElement::SL_SET_PARAMETER*

Once I know how to get this done, I can add a "SL_SET_PARAMETER" entry in my natvis and decide how to display this, but therefore I first need to explain to natvis that every CPtrList entry should be casted into a "SL_SET_PARAMETER" object.

Does anybody know how to do this?

You would have to use a <CustomListItems> tag (see CustomListItems expansion item in the MS documentation for more details). This is the most generic specification of a displayed type which allows local variables and looping.

The example that they use in their documentation is as follows:

<Type Name="ATL::CAtlMap&lt;*,*,*,*&gt;">  
    <AlternativeType Name="ATL::CMapToInterface&lt;*,*,*&gt;"/>  
    <AlternativeType Name="ATL::CMapToAutoPtr&lt;*,*,*&gt;"/>  
    <DisplayString>{{Count = {m_nElements}}}</DisplayString>  
    <Expand>  
      <CustomListItems MaxItemsPerView="5000" ExcludeView="Test">  
        <Variable Name="iBucket" InitialValue="-1" />  
        <Variable Name="pBucket" InitialValue="m_ppBins == nullptr ? nullptr : *m_ppBins" />  
        <Variable Name="iBucketIncrement" InitialValue="-1" />  

        <Size>m_nElements</Size>  
        <Exec>pBucket = nullptr</Exec>  
        <Loop>  
          <If Condition="pBucket == nullptr">  
            <Exec>iBucket++</Exec>  
            <Exec>iBucketIncrement = __findnonnull(m_ppBins + iBucket, m_nBins - iBucket)</Exec>  
            <Break Condition="iBucketIncrement == -1" />  
            <Exec>iBucket += iBucketIncrement</Exec>  
            <Exec>pBucket = m_ppBins[iBucket]</Exec>  
          </If>  
          <Item>pBucket,na</Item>  
          <Exec>pBucket = pBucket->m_pNext</Exec>  
        </Loop>  
      </CustomListItems>  
    </Expand>  
</Type>  

The only minor issue it has is that if you copy the expression that this creates from a watch window, it will look like a number casted to a pointer of the type you wanted, instead of having a nice looking array like syntax and as such will result in it not being updated if the memory location moves. If you reference a parent containing object, this isn't a big deal, just annoying.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM