UE3或者UE4的FString类型无法在内存中直接看到值,为了debug方便,需要第三方文件的协助,可以将以下两个文件UE3.natvis和UE4.natvis拷贝到$USERPROFILE/Documents/Visual Studio 2012/Visualizers 目录下,在debug的时候可以实时看到FString的值了:

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

  <!-- Epic Games, Inc. UE3 Visualizers -->
  <!-- Copy this into c:\Users\<Your user folder>\My Documents\Visual Studio 2012\Visualizers -->

  <!-- FString visualizer -->
  <Type Name="UE3::FString">
    <DisplayString Condition="ArrayNum == 0">Empty</DisplayString>
    <DisplayString Condition="ArrayNum &lt; 0">Invalid</DisplayString>
    <DisplayString Condition="ArrayMax &lt; ArrayNum">Invalid</DisplayString>
    <DisplayString Condition="ArrayMax &gt;= ArrayNum">{AllocatorInstance.Data,su}</DisplayString>
    <StringView Condition="ArrayMax &gt;= ArrayNum">AllocatorInstance.Data,su</StringView>
  </Type>

  <!-- FName visualizer -->
  <Type Name="UE3::FName">
    <DisplayString Condition="Index &gt;= Names.ArrayNum">Invalid</DisplayString>
    <DisplayString Condition="Index &lt; 0">Invalid</DisplayString>
    <DisplayString Condition="0 == (((((FNameEntry**) Names.AllocatorInstance.Data)[Index])->Index) &amp; 1) &amp;&amp; Number &gt; 0">{(((FNameEntry**) Names.AllocatorInstance.Data)[Index])->AnsiName,s}_{Number - 1}</DisplayString>
    <DisplayString Condition="1 == (((((FNameEntry**) Names.AllocatorInstance.Data)[Index])->Index) &amp; 1) &amp;&amp; Number &gt; 0">{(((FNameEntry**) Names.AllocatorInstance.Data)[Index])->UniName,su}_{Number - 1}</DisplayString>
    <DisplayString Condition="0 == (((((FNameEntry**) Names.AllocatorInstance.Data)[Index])->Index) &amp; 1)">{(((FNameEntry**) Names.AllocatorInstance.Data)[Index])->AnsiName,s}</DisplayString>
    <DisplayString Condition="1 == (((((FNameEntry**) Names.AllocatorInstance.Data)[Index])->Index) &amp; 1)">{(((FNameEntry**) Names.AllocatorInstance.Data)[Index])->UniName,su}</DisplayString>
  </Type>

  <!-- TArray visualizer -->
  <Type Name="UE3::TArray&lt;*,*&gt;|UE3::TArrayNoInit&lt;*,*&gt;">
    <DisplayString Condition="ArrayNum == 0">Empty</DisplayString>
    <DisplayString Condition="ArrayNum &lt; 0">Invalid</DisplayString>
    <DisplayString Condition="ArrayMax &lt; ArrayNum">Invalid</DisplayString>
    <DisplayString Condition="ArrayMax &gt;= ArrayNum">Num={ArrayNum}</DisplayString>
    <Expand>
      <ArrayItems Condition="ArrayNum &lt;= ArrayMax">
        <Size>ArrayNum</Size>
        <ValuePointer>($T1*) AllocatorInstance.Data</ValuePointer>
      </ArrayItems>
    </Expand>
  </Type>

  <!-- TIndirectArray visualizer -->
  <Type Name="UE3::TIndirectArray&lt;*,*&gt;">
    <DisplayString Condition="ArrayNum == 0">Empty</DisplayString>
    <DisplayString Condition="ArrayNum &lt; 0">Invalid</DisplayString>
    <DisplayString Condition="ArrayMax &lt; ArrayNum">Invalid</DisplayString>
    <DisplayString Condition="ArrayMax &gt;= ArrayNum">Num={ArrayNum}</DisplayString>
    <Expand>
      <IndexListItems Condition="ArrayNum &lt;= ArrayMax">
        <Size>ArrayNum</Size>
        <ValueNode>*(($T1**)AllocatorInstance.Data)[$i]</ValueNode>
      </IndexListItems>
    </Expand>
  </Type>

  <!-- TSparseArray visualizer -->
  <Type Name="UE3::TSparseArray&lt;*,*&gt;|UE3::TSparseArrayNoInit&lt;*,*&gt;">
    <DisplayString Condition="Data.ArrayNum == 0">Empty</DisplayString>
    <DisplayString Condition="Data.ArrayNum &lt; 0">Invalid</DisplayString>
    <DisplayString Condition="Data.ArrayMax &lt; Data.ArrayNum">Invalid</DisplayString>
    <DisplayString Condition="Data.ArrayMax &gt;= Data.ArrayNum">Num={Data.ArrayNum}</DisplayString>
    <Expand>
      <ArrayItems Condition="Data.ArrayNum &lt;= Data.ArrayMax">
        <Size>Data.ArrayNum</Size>
        <ValuePointer>($T1*) Data.AllocatorInstance.Data</ValuePointer>
      </ArrayItems>
    </Expand>
  </Type>

  <!-- TMapBase::FPair visualizer -->
  <Type Name="UE3::TMapBase&lt;*,*,*,*,*&gt;::FPair">
      <DisplayString>({Key}, {Value})</DisplayString>
  </Type>

  <!-- TMapBase visualizer -->
  <Type Name="UE3::TMapBase&lt;*,*,*,*,*&gt;">
    <DisplayString Condition="Pairs.Elements.Data.ArrayNum &lt;= 0">Empty</DisplayString>
    <DisplayString Condition="Pairs.Elements.Data.ArrayNum &lt;= Pairs.Elements.Data.ArrayMax">Num={Pairs.Elements.Data.ArrayNum - Pairs.Elements.NumFreeIndices}</DisplayString>
    <Expand>
      <IndexListItems Condition="Pairs.Elements.Data.ArrayNum &gt; 0 &amp;&amp; Pairs.Elements.Data.ArrayNum &lt;= Pairs.Elements.Data.ArrayMax">
        <Size>Pairs.Elements.Data.ArrayNum</Size>
        <ValueNode>((TSet&lt;TMapBase&lt;$T1,$T2,$T3,$T4&gt;::FPair,TMapBase&lt;$T1,$T2,$T3,$T4&gt;::KeyFuncs,$T4&gt;::FElement *) Pairs.Elements.Data.AllocatorInstance.Data + $i)-&gt;Value</ValueNode>
      </IndexListItems>
    </Expand>
  </Type>

  <!-- GFx GAtomicValueBase visualizer -->
  <Type Name="GAtomicValueBase">
    <DisplayString>{Value}</DisplayString>
  </Type>

  <!-- UObject visualizer -->
  <Type Name="UE3::UObject">
    <DisplayString Condition="Outer">(Name={Name}, Outer={Outer})</DisplayString>
    <DisplayString Condition="!Outer">(Name={Name})</DisplayString>
  </Type>

</AutoVisualizer>
UE3.natvis

相关文章: