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 < 0">Invalid</DisplayString> <DisplayString Condition="ArrayMax < ArrayNum">Invalid</DisplayString> <DisplayString Condition="ArrayMax >= ArrayNum">{AllocatorInstance.Data,su}</DisplayString> <StringView Condition="ArrayMax >= ArrayNum">AllocatorInstance.Data,su</StringView> </Type> <!-- FName visualizer --> <Type Name="UE3::FName"> <DisplayString Condition="Index >= Names.ArrayNum">Invalid</DisplayString> <DisplayString Condition="Index < 0">Invalid</DisplayString> <DisplayString Condition="0 == (((((FNameEntry**) Names.AllocatorInstance.Data)[Index])->Index) & 1) && Number > 0">{(((FNameEntry**) Names.AllocatorInstance.Data)[Index])->AnsiName,s}_{Number - 1}</DisplayString> <DisplayString Condition="1 == (((((FNameEntry**) Names.AllocatorInstance.Data)[Index])->Index) & 1) && Number > 0">{(((FNameEntry**) Names.AllocatorInstance.Data)[Index])->UniName,su}_{Number - 1}</DisplayString> <DisplayString Condition="0 == (((((FNameEntry**) Names.AllocatorInstance.Data)[Index])->Index) & 1)">{(((FNameEntry**) Names.AllocatorInstance.Data)[Index])->AnsiName,s}</DisplayString> <DisplayString Condition="1 == (((((FNameEntry**) Names.AllocatorInstance.Data)[Index])->Index) & 1)">{(((FNameEntry**) Names.AllocatorInstance.Data)[Index])->UniName,su}</DisplayString> </Type> <!-- TArray visualizer --> <Type Name="UE3::TArray<*,*>|UE3::TArrayNoInit<*,*>"> <DisplayString Condition="ArrayNum == 0">Empty</DisplayString> <DisplayString Condition="ArrayNum < 0">Invalid</DisplayString> <DisplayString Condition="ArrayMax < ArrayNum">Invalid</DisplayString> <DisplayString Condition="ArrayMax >= ArrayNum">Num={ArrayNum}</DisplayString> <Expand> <ArrayItems Condition="ArrayNum <= ArrayMax"> <Size>ArrayNum</Size> <ValuePointer>($T1*) AllocatorInstance.Data</ValuePointer> </ArrayItems> </Expand> </Type> <!-- TIndirectArray visualizer --> <Type Name="UE3::TIndirectArray<*,*>"> <DisplayString Condition="ArrayNum == 0">Empty</DisplayString> <DisplayString Condition="ArrayNum < 0">Invalid</DisplayString> <DisplayString Condition="ArrayMax < ArrayNum">Invalid</DisplayString> <DisplayString Condition="ArrayMax >= ArrayNum">Num={ArrayNum}</DisplayString> <Expand> <IndexListItems Condition="ArrayNum <= ArrayMax"> <Size>ArrayNum</Size> <ValueNode>*(($T1**)AllocatorInstance.Data)[$i]</ValueNode> </IndexListItems> </Expand> </Type> <!-- TSparseArray visualizer --> <Type Name="UE3::TSparseArray<*,*>|UE3::TSparseArrayNoInit<*,*>"> <DisplayString Condition="Data.ArrayNum == 0">Empty</DisplayString> <DisplayString Condition="Data.ArrayNum < 0">Invalid</DisplayString> <DisplayString Condition="Data.ArrayMax < Data.ArrayNum">Invalid</DisplayString> <DisplayString Condition="Data.ArrayMax >= Data.ArrayNum">Num={Data.ArrayNum}</DisplayString> <Expand> <ArrayItems Condition="Data.ArrayNum <= Data.ArrayMax"> <Size>Data.ArrayNum</Size> <ValuePointer>($T1*) Data.AllocatorInstance.Data</ValuePointer> </ArrayItems> </Expand> </Type> <!-- TMapBase::FPair visualizer --> <Type Name="UE3::TMapBase<*,*,*,*,*>::FPair"> <DisplayString>({Key}, {Value})</DisplayString> </Type> <!-- TMapBase visualizer --> <Type Name="UE3::TMapBase<*,*,*,*,*>"> <DisplayString Condition="Pairs.Elements.Data.ArrayNum <= 0">Empty</DisplayString> <DisplayString Condition="Pairs.Elements.Data.ArrayNum <= Pairs.Elements.Data.ArrayMax">Num={Pairs.Elements.Data.ArrayNum - Pairs.Elements.NumFreeIndices}</DisplayString> <Expand> <IndexListItems Condition="Pairs.Elements.Data.ArrayNum > 0 && Pairs.Elements.Data.ArrayNum <= Pairs.Elements.Data.ArrayMax"> <Size>Pairs.Elements.Data.ArrayNum</Size> <ValueNode>((TSet<TMapBase<$T1,$T2,$T3,$T4>::FPair,TMapBase<$T1,$T2,$T3,$T4>::KeyFuncs,$T4>::FElement *) Pairs.Elements.Data.AllocatorInstance.Data + $i)->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>