デバッガーでのネイティブ オブジェクトのカスタム ビューの作成
Visual Studio の Natvis フレームワークでは、[ウォッチ]、[ローカル]、[データヒント] のウィンドウのようなデバッガーの変数ウィンドウを Visual Studio でどのように表示するかをカスタマイズできます。 この設定は、以前のバージョンの Visual Studio で使用されていた autoexp.dat ファイルよりも優先され、XML 構文の使用、より高度な診断、バージョン管理、複数ファイルのサポートが可能になります。
注意
Natvis フレームワークは次の場合には視覚化に使用されません。
-
混合モードでのデスクトップ アプリケーション(Windows ストア アプリではないアプリ) のデバッグで、[Managed C++ 互換モード] オプションが Visual Studio の [オプション] ダイアログ ボックスの [デバッグ]/[全般] ページでオンになっている。
-
Visual Studio の [オプション] ダイアログ ボックスの [デバッグ]/[エディット コンティニュ] ページで、エディット コンティニュ (Visual C++) が有効になっている。
Visual Studio のデバッグ オプションを表示または編集するには、[デバッグ]、[オプションと設定] の順にクリックし、該当するページを選択します。
このトピックの内容
Natvis 視覚化を作成する理由
Natvis ファイルの使用
Natvis エラーの診断
構文リファレンス
式と書式
Condition 属性
AutoVisualizer
種類
ビジュアライザーと型の対応付け
バージョン管理
DisplayString
StringView
Expand
Item の展開
ArrayItems の展開
IndexListItems の展開
LinkedListItems の展開
TreeItems の展開
ExpandedItem の展開
Synthetic Item の展開
[HResult]
UIVisualizer
Natvis 視覚化を作成する理由
注意
コンポーネント作成者は、開発者がデバッグ中に型を簡単に検査できるように、Natvis フレームワークを使用して型の視覚化ルールを作成できます。
たとえば、次の画像に示しているのは、カスタム視覚化が適用されずに、デバッガーに表示された Windows::UI::Xaml::Controls::TextBox 型の変数です。
強調表示している行は、Text クラスの TextBox プロパティを指定するデータ メンバーを示しています。 複雑なクラス階層により、この重要なメンバーの値を簡単に見つけることができません。変数ウィンドウで深い階層をたどる必要があるためです。 さらに、デバッガーはオブジェクトによって使用されるカスタム文字列型を解釈する方法がわからないため、TextBox 内の文字列を表示できません。
同じ TextBox オブジェクト型でも、カスタム視覚化ルールが適用されると、変数ウィンドウで非常に見やすくなります。 デバッガーはクラスの重要なメンバーも共に表示でき、カスタム文字列型の基になる文字列値も表示できるようになります。
Natvis ファイルの使用
ネイティブ型の視覚化は .natvis ファイルで指定します。 A: .natvis ファイルは .natvis 拡張子が付いた単純な xml ファイル です。 スキーマは %VSINSTALLDIR%\Xml\Schemas\natvis.xsd で定義します。 Visual Studio にはいつくかの .natvis ファイルが付属しており、 それらは %VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers フォルダーにあります。 これらのファイルは、多くの一般的な型に関する視覚化ルールを格納しており、新しい型の視覚化を記述するときに例として使用できます。
natvis ファイルの 基本的な構造は 1 つ以上の Type 要素です。各 Type 要素は型の視覚化エントリを表し、型の完全修飾名が Name 属性で指定されます。
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="https://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="MyNamespace::CFoo">
.
.
</Type>
<Type Name="...">
.
.
</Type>
</AutoVisualizer>
型の視覚化を記述し始めるには、 この構造で .natvis ファイルを作成し、次のいずれかの場所に配置できます。
%VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers (管理アクセス許可が必要)
%USERPROFILE%\My Documents\Visual Studio 2013\Visualizers\
Visual Studio の拡張機能フォルダー (拡張機能マニフェスト内に NativeVisualizer アセット エントリが必要)
各デバッグ セッションの開始時、Visual Studio はこれらの場所で見つかったすべての .natvis ファイルを読み込んで 処理します (Visual Studio の再起動は不要)。 そのため、新しい視覚化の記述は簡単です。デバッグを停止し、視覚化エントリに変更を加えて、.natvis ファイルを保存した後、 デバッグを再開して変更の効果を確認するだけです。
Natvis エラーの診断
Natvis 診断は、新しい視覚化を記述するときの問題のトラブルシューティングに役立ちます。 Visual Studio デバッガーは、視覚化エントリのエラー (XML スキーマのエラー、解析できない式など) を検出するとエラーを無視するだけで、未加工の形式で型が表示するか、別の該当する視覚化を選択します。 特定の視覚化エントリが無視されている理由を把握し、その動作の基になっているエラーを確認するには、次のレジストリ値を設定することで視覚化の診断を有効にすることができます。
[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\12.0_Config\Debugger]
"EnableNatvisDiagnostics"=dword:00000001
Natvis 診断が有効になっている場合、Visual Studio の [出力] ウィンドウには、 .natvis ファイルの解析や式の評価の成功などを通知するステータス メッセージ、またはファイルや式の解析の失敗などを通知するエラー メッセージが表示されます。
構文リファレンス
式と書式
Natvis 視覚化では、C++ 式を使用して、表示するデータ項目を指定します。 デバッガーでの C++ 式の拡張機能と制限 (「ネイティブ C++ の式」を参照) に加えて、次の相違点に注意する必要があります。
Natvis 式は、現在のスタック フレームではなく視覚化されるオブジェクトのコンテキストで評価されます。 たとえば、Natvis 式で x を使用している場合、これは視覚化されるオブジェクト内の x という名前のフィールドを参照します。現在実行中の関数内の x という名前のローカル変数を参照しません。 Natvis 式内のローカル変数にアクセスすることはできませんが、グローバル変数にはアクセスできます。
Natvis 式には関数の評価や副作用は許可されません。 つまり、関数呼び出しと代入演算子は無視されます。 デバッガーの組み込み関数は、他の関数とは異なり副作用がないため、Natvis 式からは自由に呼び出すことができます。
式が変数ウィンドウに表示される方法を制御するには、「C++ の書式指定子」トピックの「Visual Studio 2012 の書式指定子」セクションで説明しているいずれかの書式指定子を使用できます。 書式指定子は Natvis によって内部的に使用されるときは無視されることに注意してください。たとえば、ArrayItems の展開の <Size> 式のような場合です。
Condition 属性
Condition 属性は必要に応じて多くの視覚化要素に使用でき、視覚化ルールを適用する条件を指定します。 Condition 属性内の式が false と評価された場合、その要素で指定した視覚化ルールは適用されません。 true と評価された場合または Condition 属性が存在しない場合は、視覚化ルールが型に適用されます。 この属性により if-else のロジックを視覚化エントリに使用できます。 たとえば次の視覚化では、スマート ポインター型に 2 つの DisplayString 要素 (後で説明) を定義しています。
<Type Name="std::auto_ptr<*>">
<DisplayString Condition="_Myptr == 0">empty</DisplayString>
<DisplayString>auto_ptr {*_Myptr}</DisplayString>
<Expand>
<ExpandedItem>_Myptr</ExpandedItem>
</Expand>
</Type>
_Myptr メンバーが null の場合、最初の DisplayString 要素の条件が true になり、したがってその要素は有効になります。 _Myptr メンバーが null でない場合、この条件が false になり、2 番目の DisplayString 要素が有効になります。
AutoVisualizer
AutoVisualizer は .natvis ファイルのルート ノードであり、 xmlns: 属性を含みます。
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="https://schemas.microsoft.com/vstudio/debugger/natvis/2010">
.
.
</AutoVisualizer
種類
視覚化エントリの完全な構文はスキーマ ファイルで見つけることができますが、基本的な視覚化エントリの構造は次のようになります。
<Type Name="[fully qualified type name]">
<DisplayString Condition="[Boolean expression]">[Display value]</DisplayString>
<Expand>
...
</Expand>
</Type>
視覚化は次の動作を指定します。
この視覚化がどの型 (Type Name 属性) に適用されるか。
その型のオブジェクトの値が DisplayString 要素によりどのように表示されるか。
そのオブジェクトの子が変数ウィンドウ (Expand ノード) で展開されたときにどのように表示されるか。
ビジュアライザーと型の対応付け
ここで示すのは、視覚化と、デバッガー ウィンドウに表示される型との対応付けを制御する一般的な規則です。
視覚化エントリは、name 属性で指定した型と、その型から派生されるすべての型に適用されます。 基底クラスと派生クラスの両方に視覚化がある場合は、派生クラスの視覚化が優先されます。
視覚化エントリの解析と検証が失敗した場合は、次に使用可能な視覚化が使用されます。
テンプレート クラス Type 要素の Name 属性には、アスタリスク (*) をワイルドカード文字として使用して、テンプレート クラス名を指定できます。
<Type Name="ATL::CAtlArray<*>"> <DisplayString>{{Count = {m_nSize}}}</DisplayString> </Type>
この例では、オブジェクトが CAtlArray<int> であっても CAtlArray<float> であっても、同じ視覚化が使用されます。 CAtlArray<float> に特定の視覚化エントリがある場合、そのエントリは汎用の視覚化エントリよりも優先されます。
マクロ $T1、$T2 などを使用することでテンプレート パラメーターを視覚化エントリで参照できることに注意してください。 これらのマクロの例を見つけるには、 Visual Studio に付属の .natvis ファイルを参照してください。
バージョン管理
Version 要素を使用して、視覚化の適用範囲を特定のモジュールとそれらのバージョンに制限すると、名前の競合を最小限に抑えることができ、型のバージョンごとに異なる視覚化を使用できます。 次に例を示します。
<Type Name="DirectUI::Border">
<Version Name="Windows.UI.Xaml.dll" Min="1.0" Max="1.5"/>
<DisplayString>{{Name = {*(m_pDO->m_pstrName)}}}</DisplayString>
<Expand>
<ExpandedItem>*(CBorder*)(m_pDO)</ExpandedItem>
</Expand>
</Type>
この例では視覚化は、バージョン 1.0 ~ 1.5 の DirectUI::Border で見つかる Windows.UI.Xaml.dll 型にのみ適用されます。 Version 要素を追加すると、視覚化の適用範囲が特定のモジュールとバージョンに制限され、不用意な対応付けは減りますが、さまざまなモジュールによって使用される共通のヘッダー ファイルで型を定義している場合、指定したモジュールにその型がないと、バージョン別の視覚化は適用されないことに注意してください。
DisplayString
DisplayString 要素は、変数の値として表示される文字列を指定します。 この要素には、任意の文字列を式と組み合わせて使用できます。 中かっこ内のすべてのものは式として解釈されて評価されます。 たとえば、次のような DisplayString エントリがあるとします。
<Type Name="CPoint">
<DisplayString>{{x={x} y={y}}}</DisplayString>
</Type>
CPoint 型の変数は次のように表示されます。
DisplayString 式では、x と y は CPoint のメンバーであり、中かっこ内にあるため、それらの値は評価されます。 この式では、二重中かっこ ({{ または }}) を使用して中かっこをエスケープする方法も示しています。
注意
DisplayString 要素でのみ、任意の文字列と中かっこ構文を使用できます。その他のすべての視覚化要素では、デバッガーによって評価される式しか使用できません。
StringView
StringView 要素は、値が組み込みテキスト ビジュアライザーに渡される式を定義します。 たとえば、ATL::CStringT に次のような視覚化があるとします。
<Type Name="ATL::CStringT<wchar_t,*>">
<DisplayString>{m_pszData,su}</DisplayString>
</Type>
CStringT オブジェクトは次のように表示されます。
視覚化により CStringT オブジェクトは変数ウィンドウに次のように表示されます。
StringView 要素を追加して、この値がテキスト ビジュアライザーによって表示できることをデバッガーに指示します。
<Type Name="ATL::CStringT<wchar_t,*>">
<DisplayString>{m_pszData,su}</DisplayString>
<StringView>m_pszData,su</StringView>
</Type>
次に示している値の横に表示されている虫眼鏡のアイコンに注目してください。 このアイコンをクリックするとテキスト ビジュアライザーが起動され、m_pszData が参照する文字列が表示されます。
注意
{m_pszData,su} 式に、値を Unicode 文字列として表示する C++ 書式指定子 su が含まれていることに注意してください。詳細については、「C++ の書式指定子」を参照してください。
Expand
Expand ノードを使用すると、視覚化された型の子が変数ウィンドウでどのように展開されるかをカスタマイズできます。 このノードでは、子要素を定義する子ノードのリストを使用できます。
注意
Expand ノードは省略可能です。
-
視覚化エントリで Expand ノードを指定しない場合、Visual Studio の既定の展開規則が使用されます。
-
Expand ノードで下位に子ノードを指定しない場合、型はデバッガー ウィンドウで展開されません。
Item の展開
Item 要素は、Expand ノードに使用される最も基本的で一般的な要素です。 Item は 1 つの子要素を定義します。 たとえば、CRect クラスに top、left、right、および bottom フィールドがあり、次の視覚化エントリがあるとします。
<Type Name="CRect">
<DisplayString>{{top={top} bottom={bottom} left={left} right={right}}}</DisplayString>
<Expand>
<Item Name="Width">right - left</Item>
<Item Name="Height">bottom - top</Item>
</Expand>
</Type>
CRect 型は次のように表示されます。
Width および Height 要素で指定した式が評価され、値の列に表示されています。 [Raw View] ノードは、カスタム展開が使用されるたびに、デバッガーによって自動的に作成されます。 前に示したスクリーンショットでこのノードは展開されています。オブジェクトの未加工のビューと視覚化がどのように異なるかがわかります。 Visual Studio の既定の展開では、基底クラスのサブツリーが作成され、基底クラスのすべてのデータ メンバーが子として一覧表示されます。
注意
Item 要素の展開により複合型が参照される場合は、Item ノード自体が展開可能になります。
ArrayItems の展開
ArrayItems ノードを使用すると、Visual Studio デバッガーによって型が配列として解釈され、その個々の要素が表示されるようになります。 std::vector の視覚化はこのノードの良い使用例です。
<Type Name="std::vector<*>">
<DisplayString>{{size = {_Mylast - _Myfirst}}}</DisplayString>
<Expand>
<Item Name="[size]">_Mylast - _Myfirst</Item>
<Item Name="[capacity]">(_Myend - _Myfirst)</Item>
<ArrayItems>
<Size>_Mylast - _Myfirst</Size>
<ValuePointer>_Myfirst</ValuePointer>
</ArrayItems>
</Expand>
</Type>
std::vector は、変数ウィンドウで展開されると、その個々の要素が表示されます。
少なくとも、ArrayItems ノードには次の式が必要です。
デバッガーが配列の長さを解釈するための Size 式 (整数に評価されることが必要)
最初の要素を参照する ValuePointer 式 (void* でない要素型のポインターであることが必要)
配列の既定の下限値は 0 です。 この値は LowerBound 要素を使用してオーバーライドできます (例については Visual Studio に付属の .natvis ファイルを参照)。
多次元配列を指定することもできます。 その場合、デバッガーでは、子要素を適切に表示するために、次のように若干追加の情報が必要になります。
<Type Name="Concurrency::array<*,*>">
<DisplayString>extent = {_M_extent}</DisplayString>
<Expand>
<Item Name="extent">_M_extent</Item>
<ArrayItems Condition="_M_buffer_descriptor._M_data_ptr != 0">
<Direction>Forward</Direction>
<Rank>$T2</Rank>
<Size>_M_extent._M_base[$i]</Size>
<ValuePointer>($T1*) _M_buffer_descriptor._M_data_ptr</ValuePointer>
</ArrayItems>
</Expand>
</Type>
Direction は、配列が行優先であるか列優先であるかを指定します。 Rank は配列のランクを指定します。 Size 要素は暗黙の $i パラメーターを受け取ります。このパラメーターは次元のインデックスに置き換えられて、その次元の配列の長さが特定されます。 前の例では、式 _M_extent.M_base[0] で 0 次元の長さ、_M_extent._M_base[1] で 1 次元の長さが特定されます。
ここでは、2 次元の Concurrency::array オブジェクトがデバッガーでどのように表示されるかを示しています。
IndexListItems の展開
ArrayItems は、配列の要素がメモリ内で連続して配置されていることを前提としてます。 デバッガーは、次の要素を取得するために、ポインターを現在の要素までインクリメントするだけです。 値ノードのインデックスを操作する必要がある場合に対応するには、IndexListItems ノードを使用できます。 ここでは、IndexListItems ノードを使用した視覚化を示しています。
<Type Name="Concurrency::multi_link_registry<*>">
<DisplayString>{{size = {_M_vector._M_index}}}</DisplayString>
<Expand>
<Item Name="[size]">_M_vector._M_index</Item>
<IndexListItems>
<Size>_M_vector._M_index</Size>
<ValueNode>*(_M_vector._M_array[$i])</ValueNode>
</IndexListItems>
</Expand>
</Type>
ArrayItems と IndexListItems の唯一の違いは、ValueNode で暗黙の $i パラメーターを使用して i 番目の要素を完全に表現していることです。
LinkedListItems の展開
視覚化された型がリンク リストを表す場合、デバッガーは LinkedListItems ノードを使用してその子を表示できます。 ここでは、この機能を使用した CAtlList 型の視覚化を示しています。
<Type Name="ATL::CAtlList<*,*>">
<DisplayString>{{Count = {m_nElements}}}</DisplayString>
<Expand>
<Item Name="Count">m_nElements</Item>
<LinkedListItems>
<Size>m_nElements</Size>
<HeadPointer>m_pHead</HeadPointer>
<NextPointer>m_pNext</NextPointer>
<ValueNode>m_element</ValueNode>
</LinkedListItems>
</Expand>
</Type>
Size 要素はリストの長さを参照します。 HeadPointer は最初の要素を参照し、NextPointer は次の要素を参照し、ValueNode は項目の値を参照します。
注意
-
NextPointer および ValueNode 式は、親リストの型ではなく、リンク リスト ノード要素のコンテキストで評価されます。前の例で、CAtlList の CNode クラス (atlcoll.h 内) はリンク リストのノードを表しています。m_pNext と m_element は、CNode クラスではなく CAtlList クラスのフィールドです。
-
ValueNode は、空にするか this を指定すると、リンク リスト ノード自体を参照できます。
TreeItems の展開
視覚化された型がツリーを表す場合、デバッガーはツリーをたどり、TreeItems ノードを使用してその子を表示できます。 ここでは、この機能を使用した std::map 型の視覚化を示しています。
<Type Name="std::map<*>">
<DisplayString>{{size = {_Mysize}}}</DisplayString>
<Expand>
<Item Name="[size]">_Mysize</Item>
<Item Name="[comp]">comp</Item>
<TreeItems>
<Size>_Mysize</Size>
<HeadPointer>_Myhead->_Parent</HeadPointer>
<LeftPointer>_Left</LeftPointer>
<RightPointer>_Right</RightPointer>
<ValueNode Condition="!((bool)_Isnil)">_Myval</ValueNode>
</TreeItems>
</Expand>
</Type>
構文は LinkedListItems ノードとほとんど同じです。 LeftPointer、RightPointer、 ValueNode は、ツリー ノード クラスのコンテキストで評価されます。ValueNode は、空のままにするか this を指定すると、ツリー ノード自体を参照できます。
ExpandedItem の展開
ExpandedItem 要素を使用すると、基底クラスまたはデータ メンバーのプロパティを視覚化された型の子であるかのように表示することで、子の集約ビューを作成できます。 指定した式が評価され、その結果の子ノードが、視覚化された型の子リストに追加されます。 たとえば、スマートポインター型 auto_ptr<vector<int>> があるとします。通常は次のように表示されます。
vector の値を表示するには、変数ウィンドウで _Myptr メンバーを通って 2 階層下位にたどる必要があります。 ExpandedItem 要素を追加することで、階層から _Myptr 変数を排除し、vector の要素を直接表示できます。
<Type Name="std::auto_ptr<*>">
<DisplayString>auto_ptr {*_Myptr}</DisplayString>
<Expand>
<ExpandedItem>_Myptr</ExpandedItem>
</Expand>
</Type>
次の例では、基底クラスのプロパティを派生クラスに集約する方法を示しています。 CPanel クラスが CFrameworkElement から派生しているとします。 基底クラス CFrameworkElement のプロパティを繰り返す代わりに、ExpandedItem ノードでは、これらのプロパティを CPanel クラスの子リストに追加できます。 派生クラスの視覚化の対応付けを無効にする nd 書式指定子がここで必要になります。 この書式指定子を使用しない場合、式 *(CFrameworkElement*)this により CPanel の視覚化が再び適用されることになります。型の対応付けルールに一致する既定の視覚化が最適と解釈されるためです。 nd 書式指定子を使用して、基底クラスの視覚化を適用するように、または基底クラスに視覚化がない場合は基底クラスの既定の展開を適用するように、デバッガーに指示します。
<Type Name="CPanel">
<DisplayString>{{Name = {*(m_pstrName)}}}</DisplayString>
<Expand>
<Item Name="IsItemsHost">(bool)m_bItemsHost</Item>
<ExpandedItem>*(CFrameworkElement*)this,nd</ExpandedItem>
</Expand>
</Type>
Synthetic Item の展開
ExpandedItem 要素は階層を排除することでデータ ビューを平坦化しますが、Synthetic ノードはその反対のことを行います。 このノードを使用すると、意図的な子要素 (式の結果ではない子要素) を作成できます。 この子要素には、その要素自体の子要素を格納できます。 次の例では、Concurrency::array 型の視覚化で Synthetic ノードを使用して、診断メッセージをユーザーに表示しています。
<Type Name="Concurrency::array<*,*>">
<DisplayString>extent = {_M_extent}</DisplayString>
<Expand>
<Item Name="extent" Condition="_M_buffer_descriptor._M_data_ptr == 0">_M_extent</Item>
<ArrayItems Condition="_M_buffer_descriptor._M_data_ptr != 0">
<Rank>$T2</Rank>
<Size>_M_extent._M_base[$i]</Size>
<ValuePointer>($T1*) _M_buffer_descriptor._M_data_ptr</ValuePointer>
</ArrayItems>
<Synthetic Name="Array" Condition="_M_buffer_descriptor._M_data_ptr == 0">
<DisplayString>Array members can be viewed only under the GPU debugger</DisplayString>
</Synthetic>
</Expand>
</Type>
[HResult]
HResult 要素を使用すると、デバッガー ウィンドウに表示される HRESULT に関する情報をカスタマイズできます。 HRValue 要素には、カスタマイズする HRESULT の 32 ビット値を格納する必要があります。 HRDescription 要素には、デバッガーに表示される情報を格納します。
<HResult Name="MY_E_COLLECTION_NOELEMENTS">
<HRValue>0xABC0123</HRValue>
<HRDescription>No elements in the collection.</HRDescription>
</HResult>
UIVisualizer
UIVisualizer 要素は、グラフィカル ビジュアライザー プラグインをデバッガーに登録するために使用します。 グラフィカル ビジュアライザー プラグインは、ダイアログ ボックスまたはその他のインターフェイスを作成して、データ型に適した方法で変数またはオブジェクトを表示します。 ビジュアライザー プラグインは VSPackage として作成し、デバッガーによって使用可能なサービスを公開する必要があります。 natvis ファイルには、 プラグインに関する登録情報 (その名前、公開されるサービスの GUID、視覚化できる型など) を格納します。
ここでは、UIVisualizer 要素の例を示しています。
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="https://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<UIVisualizer ServiceId="{5452AFEA-3DF6-46BB-9177-C0B08F318025}"
Id="1" MenuName="Vector Visualizer"/>
<UIVisualizer ServiceId="{5452AFEA-3DF6-46BB-9177-C0B08F318025}"
Id="2" MenuName="List Visualizer"/>
.
.
</AutoVisualizer>
UIVisualizer は、ServiceId - Id の属性のペアで識別されます。 ServiceId は、ビジュアライザー パッケージによって公開されるサービスの GUID です。Id は、サービスが複数のビジュアライザーを提供する場合にビジュアライザーを区別するために使用できる一意の識別子です。 前の例では、同じビジュアライザー サービスに 2 つのビジュアライザーが用意されています。
MenuName 属性は、デバッガーの変数ウィンドウで虫眼鏡のアイコンの横にあるドロップダウン メニューを開いたときに、ビジュアライザーの名前として表示されます。
.natvis ファイルで定義した各型には、 型を表示できる UI ビジュアライザーのリストを明示的に指定する必要があります。 デバッガーは、型エントリ内のビジュアライザーの参照を使用して、型と登録されたビジュアライザーとを対応付けます。 たとえば、次に示している std::vector の型エントリは、前の例での UIVisualizer を参照しています。
<Type Name="std::vector<int,*>">
<UIVisualizer ServiceId="{5452AFEA-3DF6-46BB-9177-C0B08F318025}" Id="1" />
</Type>