Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Architektura Natvis sady Visual Studio přizpůsobí způsob, jakým se nativní typy zobrazují v oknech proměnných ladicího programu, například v oknech Locals a Watch a v Datových tipech. Vizualizace Natvis vám můžou pomoct zajistit, aby byly typy, které vytváříte při ladění, viditelné.
Natvis nahrazuje soubor autoexp.dat ve starších verzích sady Visual Studio syntaxí XML, lepší diagnostikou, správou verzí a podporou více souborů.
Poznámka:
Vlastní nastavení Natvis pracují s třídami a strukturami, ale ne s typedefy.
Vizualizace Natvis
Architekturu Natvis použijete k vytvoření pravidel vizualizace pro typy, které vytvoříte, aby je vývojáři mohli snadněji zobrazit během ladění.
Například následující obrázek znázorňuje proměnnou typu Windows::UI::XAML::Controls::TextBox v okně ladicího programu bez použití vlastních vizualizací.
Zvýrazněný řádek ukazuje vlastnost Text třídy TextBox. Složitá hierarchie tříd znesnadňuje nalezení této vlastnosti. Ladicí program neví, jak interpretovat vlastní typ řetězce, takže nemůžete zobrazit řetězec uložený uvnitř textového pole.
TextBox Totéž vypadá mnohem jednodušší v okně proměnné při použití vlastních pravidel vizualizéru Natvis. Důležité členy třídy se zobrazí společně a ladicí program zobrazí základní řetězcovou hodnotu vlastního typu řetězce.
Použití souborů .natvis v projektech C++
Natvis používá soubory .natvis k určení pravidel vizualizace. Soubor .natvis je soubor XML s příponou .natvis . Schéma Natvis je definováno ve <složce> instalace VS\Xml\Schemas\1033\natvis.xsd.
Základní struktura souboru .natvis je jeden nebo více Type prvků představujících položky vizualizace. Plně kvalifikovaný název každého Type prvku je zadán v jeho Name atributu.
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="MyNamespace::CFoo">
.
.
</Type>
<Type Name="...">
.
.
</Type>
</AutoVisualizer>
Visual Studio poskytuje některé soubory .natvis ve <složce> Instalace VS\Common7\Packages\Debugger\Visualizers . Tyto soubory mají pravidla vizualizace pro mnoho běžných typů a můžou sloužit jako příklady pro psaní vizualizací pro nové typy.
Přidání souboru .natvis do projektu C++
Do libovolného projektu C++ můžete přidat soubor .natvis .
Přidání nového souboru .natvis :
Vyberte uzel projektu C++ v Průzkumníku řešení a vybertePřidat novou položku> nebo klikněte pravým tlačítkem myši na projekt a vyberte Přidat>novou položku.
Pokud nevidíte všechny šablony položek, zvolte Zobrazit všechny šablony.
V dialogovém okně Přidat novou položku vyberte Visual C++>Utility>soubor pro vizualizaci ladicího programu (.natvis).
Pojmenujte soubor a vyberte Přidat.
Nový soubor se přidá do Průzkumníka řešení a otevře se v podokně dokumentů sady Visual Studio.
Ladicí program sady Visual Studio načte soubory .natvis v projektech C++ automaticky a ve výchozím nastavení je také zahrne do souboru .pdb při sestavení projektu. Pokud ladíte sestavenou aplikaci, ladicí program načte soubor .natvis ze souboru .pdb , i když projekt nemáte otevřený. Pokud nechcete, aby byl soubor .natvis zahrnutý v souboru .pdb, můžete ho vyloučit z vytvořeného souboru .pdb .
Vyloučení souboru .natvis z souboru .pdb:
V Průzkumníku řešení vyberte soubor .natvis a vyberte ikonu Vlastnosti nebo klikněte pravým tlačítkem myši na soubor a vyberte Vlastnosti.
Klikněte na šipku vedle Vyloučeno ze sestavení a zvolte Ano, poté vyberte OK.
Poznámka:
Pro ladění spustitelných projektů použijte položky řešení k přidání všech souborů .natvis , které nejsou v souboru .pdb, protože neexistuje žádný projekt C++.
Poznámka:
Pravidla Natvis načtená z souboru .pdb se vztahují pouze na typy v modulech, na které soubor .pdb odkazuje. Pokud například Module1.pdb obsahuje položku Natvis pro typ pojmenovaný Test, vztahuje se pouze na Test třídu v Module1.dll. Pokud jiný modul také definuje třídu s názvem Test, položka Natvis Module1.pdb se na ni nevztahuje.
Instalace a registrace souboru .natvis prostřednictvím balíčku VSIX:
Balíček VSIX může instalovat a registrovat soubory .natvis . Bez ohledu na to, kde jsou nainstalované, se během ladění automaticky vyberou všechny registrované soubory .natvis .
Do balíčku VSIX zahrňte soubor .natvis . Například pro následující soubor projektu:
<?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="14.0"> <ItemGroup> <VSIXSourceItem Include="Visualizer.natvis" /> </ItemGroup> </Project>Zaregistrujte soubor .natvis v souboru source.extension.vsixmanifest :
<?xml version="1.0" encoding="utf-8"?> <PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011"> <Assets> <Asset Type="NativeVisualizer" Path="Visualizer.natvis" /> </Assets> </PackageManifest>
Umístění souborů Natvis
Soubory .natvis můžete přidat do uživatelského adresáře nebo do systémového adresáře, pokud je chcete použít pro více projektů.
Soubory .natvis se vyhodnocují v následujícím pořadí:
Všechny soubory .natvis vložené do souboru .pdb, který ladíte, pokud v načteném projektu neexistuje soubor .natvis se stejným názvem.
Všechny soubory .natvis , které jsou v načteném projektu C++ nebo řešení nejvyšší úrovně. Tato skupina zahrnuje všechny načtené projekty C++, včetně knihoven tříd, ale ne projektů v jiných jazycích.
Všechny soubory .natvis nainstalované a registrované prostřednictvím balíčku VSIX.
- Adresář Natvis specifický pro uživatele (například %USERPROFILE%\Documents\Visual Studio 2022\Visualizers).
- Adresář Natvis specifický pro uživatele (například %USERPROFILE%\Documents\Visual Studio 2019\Visualizers).
- Adresář Natvis pro celý systém (<instalační složka> sady Microsoft Visual Studio\Common7\Packages\Debugger\Visualizers). Tento adresář obsahuje soubory .natvis , které jsou nainstalovány se sadou Visual Studio. Pokud máte oprávnění správce, můžete do tohoto adresáře přidat soubory.
Úprava souborů .natvis při ladění
Při ladění projektu můžete upravit soubor .natvis v integrovaném vývojovém prostředí (IDE). Otevřete soubor ve stejné instanci sady Visual Studio, pomocí které ladíte, upravte ho a uložte. Jakmile se soubor uloží, Sledování a Místní se aktualizují, aby se odrazila změna.
Soubory .natvis můžete také přidat nebo odstranit v řešení, které ladíte, a Visual Studio přidá nebo odebere relevantní vizualizace.
Při ladění nemůžete aktualizovat soubory .natvis , které jsou vložené do souborů .pdb .
Pokud upravíte soubor .natvis mimo Visual Studio, změny se neprojeví automaticky. Chcete-li aktualizovat okna ladicího programu, můžete znovu vyhodnotit příkaz .natvisreload v okně Immediate. Změny se projeví bez restartování relace ladění.
K upgradu souboru .natvisreload na novější verzi použijte také příkaz .natvisload . Například soubor .natvis může být uložen do správy zdrojového kódu, a chcete získat nedávné změny, které provedl někdo jiný.
Výrazy a formátování
Vizualizace Natvis používají výrazy jazyka C++ k určení datových položek, které se mají zobrazit. Kromě vylepšení a omezení výrazů jazyka C++ v ladicím programu, které jsou popsány v kontextovém operátoru (C++), mějte na paměti následující:
Výrazy Natvis se vyhodnocují v kontextu vizualizovaného objektu, a nikoli v kontextu aktuálního zásobníkového rámce. Například
xve výrazu Natvis odkazuje na pole pojmenované x v vizualizovaném objektu, nikoli na místní proměnnou s názvem x v aktuální funkci. Ve výrazech Natvis nemáte přístup k místním proměnným, i když máte přístup k globálním proměnným.Výrazy Natvis neumožňují vyhodnocení funkce ani vedlejší účinky. Vyvolání funkcí a přiřazovací operátory se ignorují. Vzhledem k tomu, že vnitřní funkce ladicího programu jsou bez vedlejšího efektu, mohou být volně volány z jakéhokoli výrazu Natvis, i když jsou jiná volání funkcí zakázána.
Pokud chcete určit, jak se výraz zobrazí, můžete použít libovolný specifikátor formátu popsaný ve specifikátorech formátu v jazyce C++. Specifikátory formátu se ignorují, když je položka využívána interně v prostředí Natvis, například ve výrazu
Sizepři rozšíření ArrayItems.
Poznámka:
Vzhledem k tomu, že dokument Natvis je XML, vaše výrazy nemohou přímo používat znaky „&“, „>“, „<“ nebo posunové operátory. Tyto znaky je nutné escapovat jak v těle položky, tak ve výrazech podmínek. Například:
\<Item Name="HiByte"\>(byte)(_flags \>\> 24),x\</Item\>
\<Item Name="HiByteStatus" Condition="(_flags \& 0xFF000000) == 0"\>"None"\</Item\>
\<Item Name="HiByteStatus" Condition="(_flags \& 0xFF000000) != 0"\>"Some"\</Item\>
Zobrazení Natvis
Různá zobrazení Natvis můžete definovat tak, aby zobrazovala typy různými způsoby. Například následující fragment kódu ukazuje vizualizaci std::vector , která definuje zjednodušené zobrazení s názvem simple. Prvky DisplayString a ArrayItems se zobrazují ve výchozím zobrazení a simple zobrazení, zatímco položky [size] a [capacity] se v simple zobrazení nezobrazují.
<Type Name="std::vector<*>">
<DisplayString>{{ size={_Mylast - _Myfirst} }}</DisplayString>
<Expand>
<Item Name="[size]" ExcludeView="simple">_Mylast - _Myfirst</Item>
<Item Name="[capacity]" ExcludeView="simple">_Myend - _Myfirst</Item>
<ArrayItems>
<Size>_Mylast - _Myfirst</Size>
<ValuePointer>_Myfirst</ValuePointer>
</ArrayItems>
</Expand>
</Type>
V okně Kukátko zadejte alternativní zobrazení pomocí specifikátoru formátu zobrazení . Jednoduché zobrazení se zobrazí jako vec,view(simple):
Chyby Natvis
Když ladicí program narazí na chyby v položce vizualizace, ignoruje je. Buď zobrazí typ v nezpracované podobě, nebo vybere jinou vhodnou vizualizaci. Pomocí diagnostiky Natvis můžete zjistit, proč ladicí program ignoroval položku vizualizace, a zobrazit základní syntaxi a analyzovat chyby.
Zapnutí diagnostiky Natvis:
Otevřete panel Nástroje>Možnosti a rozbalte sekci Všechna nastavení>Ladění>Obecné. Akce Možnosti ladění> otevře podokno ve stejném oddílu.
V části Okno výstupu>Obecné nastavení výstupu nastavte možnost Diagnostické zprávy Natvis (pouze C++) na Chyba, Upozornění nebo Podrobné.
Otevřete dialogové oknoMožnosti> a rozbalte část Ladění>Obecné. Akce Možnosti ladění> otevře dialogové okno ve stejné části.
V části Okno výstupu>Obecné nastavení výstupu nastavte možnost Diagnostické zprávy Natvis (pouze C++) na Chyba, Upozornění nebo Podrobné.
Vyberte OK.
Chyby se zobrazí v okně Výstup .
Referenční příručka syntaxe Natvis
Následující prvky a atributy lze použít v souboru Natvis.
Element AutoVisualizer
Element AutoVisualizer je kořenový uzel souboru .natvis a obsahuje atribut oboru názvů xmlns: .
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
.
.
</AutoVisualizer>
Element AutoVisualizer může mít podřízené elementy Type, HResult, UIVisualizer a CustomVisualizer.
Typ prvku
Základní Type příklad vypadá takto:
<Type Name="[fully qualified type name]">
<DisplayString Condition="[Boolean expression]">[Display value]</DisplayString>
<Expand>
...
</Expand>
</Type>
Prvek Type určuje:
Jaký typ vizualizace se má použít (
Nameatribut).Jaká hodnota objektu daného typu by měla vypadat (
DisplayStringprvek).Jak by měly členové typu vypadat, když uživatel rozbalí typ v okně s proměnnými (uzel
Expand).
Šablonované třídy
Atribut Name elementu Type přijímá hvězdičku * jako zástupný znak, který lze použít pro názvy šablon třídy.
V následujícím příkladu se stejná vizualizace používá bez ohledu na to, zda je objekt CAtlArray<int> nebo CAtlArray<float>. Pokud existuje pro konkrétní CAtlArray<float>položku vizualizace, má přednost před obecnou položkou.
<Type Name="ATL::CAtlArray<*>">
<DisplayString>{{Count = {m_nSize}}}</DisplayString>
</Type>
V položce vizualizace můžete parametry šablony odkazovat pomocí maker $T1, $T2 atd. Příklady těchto maker najdete v souborech .natvis, které jsou součástí sady Visual Studio.
Porovnávání typů vizualizéru
Pokud se nepovede ověřit položku vizualizace, použije se další dostupná vizualizace.
Zděděný atribut
Volitelný Inheritable atribut určuje, zda se vizualizace vztahuje pouze na základní typ, nebo na základní typ a všechny odvozené typy. Výchozí hodnota atributu Inheritable je true.
V následujícím příkladu se vizualizace vztahuje pouze na BaseClass typ:
<Type Name="Namespace::BaseClass" Inheritable="false">
<DisplayString>{{Count = {m_nSize}}}</DisplayString>
</Type>
Atribut Priorita
Volitelný Priority atribut určuje pořadí, ve kterém se mají použít alternativní definice, pokud se definice nepodaří analyzovat. Možné hodnoty Priority jsou: Low, , MediumLowMedium, MediumHigha High. Výchozí hodnota je Medium. Atribut Priority rozlišuje pouze priority ve stejném souboru .natvis .
Následující příklad nejprve analyzuje položku, která odpovídá hodnotě STL 2015. Pokud se to nepodaří analyzovat, použije alternativní položku pro verzi STL 2013:
<!-- VC 2013 -->
<Type Name="std::reference_wrapper<*>" Priority="MediumLow">
<DisplayString>{_Callee}</DisplayString>
<Expand>
<ExpandedItem>_Callee</ExpandedItem>
</Expand>
</Type>
<!-- VC 2015 -->
<Type Name="std::reference_wrapper<*>">
<DisplayString>{*_Ptr}</DisplayString>
<Expand>
<Item Name="[ptr]">_Ptr</Item>
</Expand>
</Type>
Volitelný atribut
Atribut můžete umístit Optional na libovolný uzel. Pokud se dílčí výraz uvnitř volitelného uzlu nepodaří analyzovat, ladicí program tento uzel ignoruje, ale použije zbytek Type pravidel. V následujícím typu [State] není volitelný, ale [Exception] je nepovinný. Pokud MyNamespace::MyClass má pole s názvem _M_exceptionHolder, se zobrazí uzel [State] i uzel [Exception], ale pokud neexistuje žádné _M_exceptionHolder pole, se zobrazí pouze uzel [State].
<Type Name="MyNamespace::MyClass">
<Expand>
<Item Name="[State]">_M_State</Item>
<Item Name="[Exception]" Optional="true">_M_exceptionHolder</Item>
</Expand>
</Type>
Podmínkový atribut
Volitelný Condition atribut je k dispozici pro mnoho prvků vizualizace a určuje, kdy se má použít pravidlo vizualizace. Pokud se výraz uvnitř atributu podmínky přeloží na false, pravidlo vizualizace se nepoužije. Pokud se vyhodnotí jako truenebo neexistuje žádný Condition atribut, vizualizace se použije. Tento atribut můžete použít pro logiku if-else v položkách vizualizace.
Například následující vizualizace obsahuje dva DisplayString prvky pro typ inteligentního ukazatele. Když je člen prázdný, podmínka prvního prvku DisplayString se vyhodnotí na true, takže se zobrazí formulář.
_Myptr Pokud člen není prázdný, podmínka se vyhodnotí jako falsea druhý DisplayString prvek se zobrazí.
<Type Name="std::auto_ptr<*>">
<DisplayString Condition="_Myptr == 0">empty</DisplayString>
<DisplayString>auto_ptr {*_Myptr}</DisplayString>
<Expand>
<ExpandedItem>_Myptr</ExpandedItem>
</Expand>
</Type>
Atributy IncludeView a ExcludeView
IncludeView Atributy ExcludeView určují prvky, které se mají zobrazit nebo nezobrazují v konkrétních zobrazeních. Například v následující specifikaci std::vector Natvis zobrazení simple nezobrazuje položky [size] a [capacity].
<Type Name="std::vector<*>">
<DisplayString>{{ size={_Mylast - _Myfirst} }}</DisplayString>
<Expand>
<Item Name="[size]" ExcludeView="simple">_Mylast - _Myfirst</Item>
<Item Name="[capacity]" ExcludeView="simple">_Myend - _Myfirst</Item>
<ArrayItems>
<Size>_Mylast - _Myfirst</Size>
<ValuePointer>_Myfirst</ValuePointer>
</ArrayItems>
</Expand>
</Type>
Můžete použít IncludeView a ExcludeView atributy na typech a jednotlivých členech.
Prvek verze
Element Version vymezuje položku vizualizace na konkrétní modul a verzi. Tento Version prvek pomáhá vyhnout se kolizím názvů, snižuje neúmyslné neshody a umožňuje různé vizualizace pro různé verze typů.
Pokud společný hlavičkový soubor, který používá různé moduly, definuje typ, zobrazí se vizualizace s verzí pouze v případě, že je typ v zadané verzi modulu.
V následujícím příkladu je vizualizace použitelná pouze pro DirectUI::Border typ nalezený ve Windows.UI.Xaml.dll verzi 1.0 až 1.5.
<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>
Nepotřebujete obojí Min a Max. Jedná se o volitelné atributy. Nepodporují se žádné zástupné znaky.
Atribut Name je ve formátu název_souboru.ext, například hello.exe nebo some.dll. Nejsou povoleny žádné názvy cest.
DisplayString element
Element DisplayString určuje řetězec, který se má zobrazit jako hodnota proměnné. Přijímá libovolné řetězce obsahující výrazy. Cokoli uvnitř složených závorek se interpretuje jako výraz. Například následující DisplayString položka:
<Type Name="CPoint">
<DisplayString>{{x={x} y={y}}}</DisplayString>
</Type>
Znamená, že proměnné typu CPoint se zobrazují jako na tomto obrázku:
Ve výrazu DisplayString, x a y, které jsou členy CPoint, jsou uvnitř složených závorek, takže jejich hodnoty jsou vyhodnoceny. Příklad také ukazuje, jak můžete escapovat složenou závorku použitím dvojitých složených závorek ( {{ nebo }} ).
Poznámka:
Element DisplayString je jediný element, který přijímá libovolné řetězce a syntaxi složených závorek. Všechny ostatní prvky vizualizace přijímají pouze výrazy, které ladicí program může vyhodnotit.
StringView: prvek
Element StringView definuje hodnotu, kterou ladicí program může odeslat do integrovaného vizualizéru textu. Například pro následující vizualizaci typu ATL::CStringT:
<Type Name="ATL::CStringT<wchar_t,*>">
<DisplayString>{m_pszData,su}</DisplayString>
</Type>
Objekt CStringT se zobrazí v okně proměnné jako v tomto příkladu:
Přidání elementu StringView říká ladicímu programu, že může zobrazit hodnotu jako textovou vizualizaci.
<Type Name="ATL::CStringT<wchar_t,*>">
<DisplayString>{m_pszData,su}</DisplayString>
<StringView>m_pszData,su</StringView>
</Type>
Během ladění můžete vybrat ikonu lupy vedle proměnné a pak vybrat Vizualizér textu , aby se zobrazil řetězec, na který m_pszData odkazuje.
Výraz {m_pszData,su} obsahuje specifikátor formátu C++ su, který zobrazí hodnotu jako řetězec Unicode. Další informace naleznete v tématu Specifikátory formátu v jazyce C++.
Rozbalit prvek
Volitelný uzel Expand upravuje podřízené prvky vizualizovaného typu při rozbalení typu v okně proměnné. Uzel Expand přijímá seznam podřízených uzlů, které definují podřízené prvky.
Pokud není uzel
Expandspecifikován v položce vizualizace, podřízené uzly používají výchozí pravidla rozšíření.Pokud je uzel
Expandzadán bez podřízených uzlů, typ není možné rozbalit v oknech ladicího programu.
Rozšíření položky
Prvek Item je nejzásadnější a nejběžnější prvek v Expand uzlu.
Item definuje jeden podřízený prvek. Například CRect třída s poli top, left, righta bottom má následující položku vizualizace:
<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>
Typ CRect vypadá v okně ladicího programu takto: příklad.
Ladicí program vyhodnotí výrazy zadané v prvcích Width a Height a zobrazí hodnoty ve sloupci Hodnota v okně proměnných.
Ladicí program automaticky vytvoří uzel [Nezpracované zobrazení] pro každé vlastní rozšíření. Předchozí snímek obrazovky zobrazuje rozbalený uzel [Nezpracované zobrazení] a ukazuje, jak se výchozí nezpracované zobrazení objektu liší od vizualizace Natvis. Výchozí rozšíření vytvoří podstrom základní třídy a vypíše všechny datové členy základní třídy jako podřízené položky.
Poznámka:
Pokud výraz prvku položky odkazuje na komplexní typ, uzel Item samotný je rozbalitelný.
Rozšíření ArrayItems
Pomocí uzlu ArrayItems umožníte ladicímu programu sady Visual Studio interpretovat typ jako pole a zobrazit jeho jednotlivé prvky. Vizualizace pro std::vector je dobrým příkladem:
<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>
Při rozbalení v okně proměnné se std::vector zobrazí jeho jednotlivé prvky:
Uzel ArrayItems musí mít:
- Výraz
Size(který musí být vyhodnocen jako celé číslo) umožňující ladicímu programu pochopit délku pole. -
ValuePointerVýraz, který odkazuje na první prvek (což musí být ukazatel typu prvku, který nenívoid*).
Výchozí hodnota dolní hranice pole je 0. K přepsání hodnoty použijte LowerBound element. Soubory .natvis dodávané se sadou Visual Studio obsahují příklady.
Poznámka:
Operátor [] můžete použít například s libovolnou jednorozměrnou vizualizací pole vector[i], která využívá ArrayItems, i když samotný typ (například CATLArray) tento operátor nepovoluje.
Můžete také zadat vícerozměrná pole. V takovém případě ladicí program potřebuje k správnému zobrazení podřízených prvků o něco více informací:
<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>
<LowerBound>0</LowerBound>
</ArrayItems>
</Expand>
</Type>
-
Directionurčuje, jestli je pole v řádkovém pořadí nebo sloupcovém pořadí. -
Rankurčuje pořadí pole. - Element
Sizepřijímá implicitní$iparametr, který nahradí indexem dimenze, aby zjistil délku pole v této dimenzi.- V předchozím příkladu by výraz
_M_extent.M_base[0]měl dát délku 0. dimenze,_M_extent._M_base[1]první a tak dále.
- V předchozím příkladu by výraz
- Určuje
LowerBounddolní mez každé dimenze pole. U multidimenzionálních polí můžete zadat výraz, který používá implicitní$iparametr. Parametr$ije nahrazen indexem dimenze, aby našel dolní mez pole v dané dimenzi.- V předchozím příkladu začínají všechny dimenze na 0. Pokud jste však měli
($i == 1) ? 1000 : 100dolní mez, začíná 0. dimenze na 100 a první dimenze začíná na 1000.- například
[100, 1000], [100, 1001], [100, 1002], ... [101, 1000], [101, 1001],...
- například
- V předchozím příkladu začínají všechny dimenze na 0. Pokud jste však měli
Takto vypadá dvojrozměrný Concurrency::array objekt v okně ladicího programu:
Rozšíření IndexListItems
Rozšíření ArrayItems lze použít pouze v případě, že jsou prvky pole uspořádány souvisle v paměti. Ladicí program se dostane k dalšímu prvku jednoduše tím, že zvýší svůj ukazatel. Pokud potřebujete manipulovat s indexem uzlu hodnoty, použijte IndexListItems uzly. Tady je vizualizace s IndexListItems uzlem:
<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>
Jediný rozdíl mezi ArrayItems a IndexListItems je ValueNode, který očekává úplný výraz pro i-tý prvek s implicitním parametrem $i.
Poznámka:
Operátor [] můžete například použít s libovolnou jednorozměrnou vizualizací pole, která používá IndexListItems, i když samotný typ (například CATLArray) tento operátor nepovoluje.
Rozšíření LinkedListItems
Pokud vizualizovaný typ představuje propojený seznam, může ladicí program zobrazit jeho potomky pomocí uzlu LinkedListItems. Následující vizualizace pro CAtlList typ používá LinkedListItems:
<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>
Prvek Size odkazuje na délku seznamu.
HeadPointer odkazuje na první prvek, NextPointer odkazuje na další prvek a ValueNode odkazuje na hodnotu položky.
Ladicí program vyhodnotí výrazy NextPointer a ValueNode v kontextu prvku uzlu LinkedListItems, nikoli v kontextu nadřazeného typu seznamu. V předchozím příkladu CAtlList má CNode třídu (nalezenou v atlcoll.h) , která je uzlem propojeného seznamu.
m_pNext a m_element jsou pole této CNode třídy, nikoli CAtlList třídy.
ValueNode může být ponechána prázdná nebo se používá this k odkazování na LinkedListItems samotný uzel.
Rozšíření CustomListItems
Rozšíření CustomListItems umožňuje napsat vlastní logiku pro procházení datové struktury, jako je například hashtable. Umožněte CustomListItems vizualizovat datové struktury, které mohou používat výrazy jazyka C++ pro všechny potřebné výpočty, ale neodpovídají vzoru pro ArrayItems, IndexListItems nebo LinkedListItems.
Můžete použít Exec ke spuštění kódu uvnitř CustomListItems rozšíření pomocí proměnných a objektů definovaných v rozšíření. Můžete použít logické operátory, aritmetické operátory a operátory přiřazení s Exec. Nemůžete použít Exec k vyhodnocení funkcí, s výjimkou vnitřních funkcí ladicího programu podporovaných vyhodnocovačem výrazů jazyka C++.
Následující vizualizér CAtlMap je vynikajícím příkladem, kde CustomListItems je vhodný.
<Type Name="ATL::CAtlMap<*,*,*,*>">
<AlternativeType Name="ATL::CMapToInterface<*,*,*>"/>
<AlternativeType Name="ATL::CMapToAutoPtr<*,*,*>"/>
<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>
Rozšíření TreeItems
Pokud vizualizovaný typ představuje strom, ladicí program může strom procházet a zobrazit jeho potomky pomocí uzlu TreeItems. Tady je vizualizace typu std::map pomocí TreeItems uzlu:
<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>
Syntaxe je podobná LinkedListItems uzlu.
LeftPointer, RightPointera ValueNode jsou vyhodnoceny v kontextu třídy uzlu stromu.
ValueNode může být ponechána prázdná nebo použít this k odkazování na TreeItems samotný uzel.
Rozšíření položky ExpandedItem
Element ExpandedItem generuje agregované podřízené zobrazení tím, že zobrazuje vlastnosti základních tříd nebo datových členů, jako by byly podřízenými prvky vizualizovaného typu. Debugger vyhodnotí zadaný výraz a přidá podřízené uzly výsledku do seznamu podřízených uzlů vizualizovaného typu.
Například typ auto_ptr<vector<int>> inteligentního ukazatele se obvykle zobrazuje takto:
Pokud chcete zobrazit hodnoty vektoru, musíte postoupit o dvě úrovně v okně proměnné, a to projit členem _Myptr. Přidáním elementu ExpandedItem můžete eliminovat proměnnou _Myptr z hierarchie a přímo zobrazit vektorové prvky:
<Type Name="std::auto_ptr<*>">
<DisplayString>auto_ptr {*_Myptr}</DisplayString>
<Expand>
<ExpandedItem>_Myptr</ExpandedItem>
</Expand>
</Type>
Následující příklad ukazuje, jak agregovat vlastnosti ze základní třídy v odvozené třídě. Předpokládejme, že CPanel třída je odvozena od CFrameworkElement. Místo opakování vlastností, které pocházejí ze základní CFrameworkElement třídy, ExpandedItem připojí vizualizace uzlu tyto vlastnosti do podřízeného CPanel seznamu třídy.
<Type Name="CPanel">
<DisplayString>{{Name = {*(m_pstrName)}}}</DisplayString>
<Expand>
<Item Name="IsItemsHost">(bool)m_bItemsHost</Item>
<ExpandedItem>*(CFrameworkElement*)this,nd</ExpandedItem>
</Expand>
</Type>
Zde je nezbytný specifikátor formátu nd , který vypne vizualizaci odpovídající odvozené třídě. Jinak by výraz *(CFrameworkElement*)this způsobil opětovné použití vizualizace CPanel, protože podle výchozích pravidel párování typů vizualizací je považována za nejvhodnější. Specifikátor formátu nd použijte k pokynu ladicímu programu, aby používal vizualizaci základní třídy, nebo výchozí rozšíření, pokud základní třída nemá žádnou vizualizaci.
Rozšíření syntetických položek
Ačkoli prvek ExpandedItem poskytuje ploché zobrazení dat odstraněním hierarchií, uzel Synthetic dělá opak. Umožňuje vytvořit virtuální podřízený prvek, který není výsledkem výrazu. Umělý prvek může mít své vlastní podřízené prvky. V následujícím příkladu vizualizace pro Concurrency::array typ používá Synthetic uzel k zobrazení diagnostické zprávy uživateli:
<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>
Vnitřní rozšíření
Vlastní vnitřní funkce, kterou lze volat z výrazu. Prvek <Intrinsic> musí být doprovázen komponentou ladicího programu, která implementuje funkci prostřednictvím rozhraní IDkmIntrinsicFunctionEvaluator140. Další informace o implementaci vlastní vnitřní funkce naleznete v tématu Implementace vlastní vnitřní funkce NatVis.
<Type Name="std::vector<*>">
<Intrinsic Name="size" Expression="(size_t)(_Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst)" />
<Intrinsic Name="capacity" Expression="(size_t)(_Mypair._Myval2._Myend - _Mypair._Myval2._Myfirst)" />
<DisplayString>{{ size={size()} }}</DisplayString>
<Expand>
<Item Name="[capacity]" ExcludeView="simple">capacity()</Item>
<Item Name="[allocator]" ExcludeView="simple">_Mypair</Item>
<ArrayItems>
<Size>size()</Size>
<ValuePointer>_Mypair._Myval2._Myfirst</ValuePointer>
</ArrayItems>
</Expand>
</Type>
HResult element
Element HResult umožňuje přizpůsobit informace zobrazené pro HRESULT v oknech ladicího programu. Prvek HRValue musí obsahovat 32bitovou hodnotu HRESULT , která se má přizpůsobit. Element HRDescription obsahuje informace, které se mají zobrazit v okně ladicího programu.
<HResult Name="MY_E_COLLECTION_NOELEMENTS">
<HRValue>0xABC0123</HRValue>
<HRDescription>No elements in the collection.</HRDescription>
</HResult>
UIVisualizer element
Prvek UIVisualizer registruje plugin grafického vizualizátoru s ladicím programem. Grafický vizualizér vytvoří dialogové okno nebo jiné rozhraní, které zobrazuje proměnnou nebo objekt způsobem konzistentním s jeho datovým typem. Plugin vizualizéru musí být vytvořený jako balíček VSPackage a musí poskytnout službu, kterou může ladicí program využívat. Soubor .natvis obsahuje informace o registraci modulu plug-in, jako je jeho název, globálně jedinečný identifikátor (GUID) vystavené služby a typy, které může vizualizovat.
Tady je příklad elementu UIVisualizer:
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://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>
Pár atributů
ServiceId-IdidentifikujeUIVisualizer. Jedná seServiceIdo identifikátor GUID služby, který balíček vizualizéru zveřejňuje.Idje jedinečný identifikátor, který rozlišuje vizualizéry, pokud služba poskytuje více než jeden. V předchozím příkladu poskytuje stejná služba vizualizéru dva vizualizéry.Atribut
MenuNamedefinuje název vizualizéru, který se zobrazí v rozevíracím seznamu vedle ikony lupy v ladicím programu. Například:
menu
Každý typ definovaný v souboru .natvis musí explicitně zobrazit všechny vizualizéry uživatelského rozhraní, které ho mohou zobrazit. Ladicí program porovnává odkazy na vizualizéry v položkách typu s registrovanými vizualizéry. Například následující položka typu pro std::vector odkazuje na UIVisualizer v předchozím příkladu.
<Type Name="std::vector<int,*>">
<UIVisualizer ServiceId="{5452AFEA-3DF6-46BB-9177-C0B08F318025}" Id="1" />
</Type>
Můžete vidět příklad UIVisualizer v rozšíření Image Watch používaného k zobrazení bitmap uložených v paměti.
CustomVisualizer prvek
CustomVisualizer je bod rozšiřitelnosti, který určuje rozšíření VSIX, které napíšete pro řízení vizualizací v editoru Visual Studio Code. Další informace o psaní rozšíření VSIX najdete v sadě Visual Studio SDK.
Je mnohem více práce napsat vlastní vizualizér než definice Natvis XML, ale nemáte omezení ohledně toho, co Natvis dělá nebo nepodporuje. Vlastní vizualizéry mají přístup k úplné sadě rozhraní API rozšiřitelnosti ladicího programu, která můžou dotazovat a upravovat proces ladění nebo komunikovat s jinými částmi sady Visual Studio.
U elementů CustomVisualizer můžete použít atributy Condition, IncludeView a ExcludeView.
Omezení
Vlastní nastavení Natvis pracují s třídami a strukturami, ale ne s typedefy.
Natvis nepodporuje vizualizéry pro primitivní typy (například int, bool), ani pro ukazatele na primitivní typy. V tomto scénáři je jednou z možností použití specifikátoru formátu vhodného pro váš případ použití. Pokud například používáte double* mydoublearray v kódu, můžete použít specifikátor formátu pole v okně Kukátko ladicího programu, například výraz mydoublearray, [100], který zobrazuje prvních 100 prvků.