Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A Visual Studio Natvis keretrendszer testre szabja a natív típusok megjelenését a hibakereső változóablakokban, például a Helyi és Watch ablakaiban, valamint Adattippek. A Natvis-vizualizációk segíthetnek láthatóbbá tenni a hibakeresés során létrehozott típusokat.
A Natvis a Visual Studio korábbi verzióiban lévő autoexp.dat fájlt XML-szintaxisra, jobb diagnosztikára, verziószámozásra és több fájltámogatásra cseréli.
Jegyzet
A Natvis-testreszabások osztályokkal és struktúrákkal működnek, de nem típusdefiníciókkal.
Natvis-vizualizációk
A Natvis-keretrendszer használatával vizualizációs szabályokat hozhat létre a létrehozott típusokhoz, hogy a fejlesztők könnyebben láthassák őket a hibakeresés során.
Az alábbi ábrán például egy windowsos típusú változó látható::UI::XAML::Controls::TextBox hibakereső ablakban egyéni vizualizációk alkalmazása nélkül.
A kiemelt sor a Text osztály TextBox tulajdonságát jeleníti meg. Az összetett osztályhierarchia megnehezíti a tulajdonság megtalálását. A hibakereső nem tudja, hogyan értelmezze az egyéni sztringtípust, ezért nem látja a szövegmezőben tárolt sztringet.
Ugyanez a TextBox sokkal egyszerűbbnek tűnik a változóablakban a Natvis egyéni vizualizációs szabályainak alkalmazásakor. Az osztály fontos tagjai egyesített módon jelennek meg, és a hibakereső megjeleníti az egyedi karakterlánc típus mögöttes karakterláncértékét.
TextBox-adatok 
.natvis-fájlok használata C++-projektekben
A Natvis .natvis fájlokat használ a vizualizációs szabályok megadásához. A .natvis fájl egy .natvis kiterjesztésű XML-fájl. A Natvis-séma az <VS telepítési mappájában>\Xml\Schemas\1033\natvis.xsd.
A .natvis fájl alapstruktúrája egy vagy több Type elem, amely vizualizációs bejegyzéseket jelöl. Az egyes Type elemek teljes neve a Name attribútumban van megadva.
<?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>
A Visual Studio .natvis fájlokat biztosít a <VS telepítési mappájában>\Common7\Packages\Debugger\Visualizers mappában. Ezek a fájlok számos gyakori típushoz rendelkeznek vizualizációs szabályokkal, és példaként szolgálhatnak az új típusok vizualizációinak megírására.
.natvis-fájl hozzáadása C++ projekthez
Egy .natvis fájlt bármely C++ projekthez hozzáadhat.
Új .natvis fájl hozzáadása:
Válassza a C++ projektcsomópontot Megoldáskezelő, és válassza Project>Új elem hozzáadásalehetőséget, vagy kattintson a jobb gombbal a projektre, és válassza >Új elem hozzáadásalehetőséget.
Ha nem látja az összes elemsablont, válassza a Az összes sablon megjelenítéselehetőséget.
Az Új elem hozzáadása párbeszédpanelen válassza Visual C++>Segédprogram>Hibakereső vizualizációs fájl (.natvis)lehetőséget.
Nevezze el a fájlt, és válassza a hozzáadása lehetőséget.
Az új fájl hozzáadódik a Megoldáskezelőhöz, és megnyitva jelenik meg a Visual Studio dokumentumpaneljén.
A Visual Studio hibakeresője automatikusan betölti .natvis fájlokat a C++ projektekben, és alapértelmezés szerint a .pdb fájlban is tartalmazza őket a projekt buildelésekor. A beépített alkalmazás hibakeresése esetén a hibakereső betölti a .natvis fájlt a .pdb fájlból, még akkor is, ha nincs megnyitva a projekt. Ha nem szeretné, hogy a .natvis fájl szerepeljön a .pdb, kizárhatja azt a beépített .pdb fájlból.
.natvis fájl kizárása .pdb:
Válassza a .natvis fájlt Megoldáskezelő, és válassza a Tulajdonságok ikont, vagy kattintson a jobb gombbal a fájlra, és válassza a Tulajdonságoklehetőséget.
A legördülő listában kattintson a Ki van zárva a buildből melletti nyílra, válassza ki az Igenlehetőséget, és válassza a OKlehetőséget.
Jegyzet
Végrehajtható projektek hibakereséséhez használja a megoldáselemeket a .pdb-ben nem található .natvis-fájlok hozzáadásához, mert nincs elérhető C++ projekt.
Jegyzet
A .pdb betöltött Natvis-szabályok csak azokra a típusokra vonatkoznak a modulokban, amelyekre a .pdb hivatkozik. Ha például Module1.pdb egy Testnevű típushoz natvis bejegyzéssel rendelkezik, az csak a Test osztályára vonatkozik. Ha egy másik modul is definiál egy osztályt, Testakkor a Module1.pdb Natvis bejegyzés nem vonatkozik rá.
.natvis fájl telepítése és regisztrálása VSIX-csomagon keresztül:
A VSIX-csomagok telepíthetnek és regisztrálhatnak .natvis fájlokat. Függetlenül attól, hogy hol vannak telepítve, a hibakeresés során a rendszer automatikusan felveszi az összes regisztrált .natvis-fájlt .
Vegye fel a .natvis fájlt a VSIX-csomagba. Például a következő projektfájlhoz:
<?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>Regisztrálja a .natvis fájlt a source.extension.vsixmanifest fájlban:
<?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>
Natvis-fájlhelyek
Hozzáadhat .natvis fájlokat a felhasználói címtárhoz vagy egy rendszerkönyvtárhoz, ha azt szeretné, hogy több projektre is vonatkozzanak.
A .natvis fájlok kiértékelése a következő sorrendben történik:
Minden .natvis fájl, amely a .pdb fájlba van beágyazva, és amelyet éppen hibakeresnek, kivéve, ha azonos nevű fájl létezik a betöltött projektben.
Minden .natvis fájl, amely egy betöltött C++ projektben vagy legfelső szintű megoldásban található. Ez a csoport tartalmazza az összes betöltött C++ projektet, beleértve az osztálytárakat is, más nyelveken nem.
A VSIX-csomagon keresztül telepített és regisztrált .natvis fájlok.
- A felhasználóspecifikus Natvis könyvtár (például %USERPROFILE%\Documents\Visual Studio 2022\Visualizers).
- A felhasználóspecifikus Natvis könyvtár (például %USERPROFILE%\Documents\Visual Studio 2019\Visualizers).
- A rendszerszintű Natvis könyvtár (<Microsoft Visual Studio telepítési mappa>\Common7\Packages\Debugger\Visualizers). Ez a könyvtár tartalmazza a Visual Studióval telepített .natvis fájlokat. Ha rendszergazdai engedélyekkel rendelkezik, fájlokat adhat hozzá ehhez a könyvtárhoz.
.natvis-fájlok módosítása hibakeresés közben
A projekt hibakeresése közben módosíthatja a .natvis fájlt az IDE-ben. Nyissa meg a fájlt a Visual Studio ugyanazon példányában, amellyel hibakeresést végzett, módosítsa és mentse. Amint a fájlt menti, a Watch és a Helyi változók ablakok frissülnek, hogy tükrözzék a változást.
A hibakeresési megoldásban .natvis fájlokat is hozzáadhat vagy törölhet, a Visual Studio pedig hozzáadja vagy eltávolítja a megfelelő vizualizációkat.
Hibakeresés közben nem frissítheti .natvis fájlokat, amelyek .pdb fájlokba vannak beágyazva.
Ha a Visual Studión kívül módosítja a .natvis fájlt, a módosítások nem lépnek érvénybe automatikusan. A hibakereső ablakainak frissítéséhez újraértékelheti a .natvisreload parancsot az Azonnali ablakban. A módosítások a hibakeresési munkamenet újraindítása nélkül lépnek érvénybe.
A .natvisreload paranccsal frissítse a .natvis fájlt egy újabb verzióra. Előfordulhat például, hogy a .natvis fájl be van jelölve a forrásvezérlőbe, és fel szeretné venni azokat a módosításokat, amelyeket valaki más végzett.
Kifejezések és formázás
A Natvis-vizualizációk C++ kifejezésekkel határozzák meg a megjelenítendő adatelemeket. A hibakereső C++ kifejezéseinek fejlesztései és korlátozásai mellett, amelyeket Környezet operátor (C++)ismertet, vegye figyelembe a következőket:
A Natvis-kifejezések kiértékelése a vizualizálandó objektum kontextusában történik, nem az aktuális veremkeretben. Egy Natvis-kifejezés
xpéldául a vizualizáció alatt álló objektum x nevű mezőre hivatkozik, nem pedig az aktuális függvényben x nevű helyi változóra. A Natvis-kifejezésekben nem férhet hozzá a helyi változókhoz, bár globális változókhoz is hozzáférhet.A Natvis-kifejezések nem teszik lehetővé a függvények kiértékelését és a mellékhatásokat. A függvényhívások és a hozzárendelési operátorok figyelmen kívül lesznek hagyva. Mivel hibakereső belső függvények mellékhatásmentesek, bármely Natvis-kifejezésből szabadon meghívhatók, még akkor is, ha más függvényhívások nem engedélyezettek.
A kifejezések megjelenítésének szabályozásához használhatja a C++formátumjelölőiben leírt formátumjelölőket. A formátumjelölőket figyelmen kívül hagyják, amikor a bejegyzést a Natvis belsőleg használja, például a
Sizekifejezés a ArrayItems bővítésben.
Jegyzet
Mivel a Natvis-dokumentum XML, a kifejezések nem használhatják közvetlenül az ampersand, nagyobb, kisebb vagy shift operátorokat. Ezeket a karaktereket az elem törzsében és a feltétel kifejezésekben is le kell cserélnie. Például:
\<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\>
Natvis-nézetek
Különböző Natvis-nézeteket határozhat meg, hogy különböző módokon jelenítsen meg típusokat. Az alábbi kódrészlet például egy olyan vizualizációt std::vector jelenít meg, amely egy simple nevű, egyszerűsített nézetet határoz meg. A DisplayString és a ArrayItems elemek az alapértelmezett nézetben és a simple nézetben jelennek meg, míg a [size] és [capacity] elemek nem jelennek meg a simple nézetben.
<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>
A Watch ablakban használja a ,view formátumjelzőt egy alternatív nézet megadásához. Az egyszerű nézet vec,view(simple):
Natvis-hibák
Amikor a hibakereső hibát tapasztal egy vizualizációs bejegyzésben, figyelmen kívül hagyja őket. Vagy nyers formában jeleníti meg a típust, vagy kiválaszt egy másik megfelelő vizualizációt. A Natvis-diagnosztikával megértheti, hogy a hibakereső miért hagyott figyelmen kívül egy vizualizációs bejegyzést, és megtekintheti az alapul szolgáló szintaxist és elemzési hibákat.
Natvis-diagnosztika bekapcsolása:
Nyissa meg az Eszközök>beállításai panelt, és bontsa ki a Minden beállítás>hibakeresése általános szakaszt>. A Hibakeresési>beállítások művelet megnyitja a panelt ugyanahhoz a szakaszhoz.
A Kimeneti ablak>általános kimeneti beállításainál állítsa a Natvis diagnosztikai üzenetek (csak C++ esetén) beállítást Hiba, Vigyázat vagy Részletes értékre.
Nyissa meg az Eszközök>beállításai párbeszédpanelt, és bontsa ki azÁltalános>. A Hibakeresési>beállítások művelet ugyanahhoz a szakaszhoz nyitja meg a párbeszédpanelt.
A Kimeneti ablak>Általános kimeneti beállításoknál állítsa a Natvis diagnosztikai üzenetek (csak C++ esetén) beállítást Hiba, Figyelmeztetés vagy Részletes értékre.
Kattintson az OK gombra.
A hibák a Kimeneti ablakban jelennek meg.
Natvis szintaxisra vonatkozó hivatkozás
A Natvis-fájlban az alábbi elemek és attribútumok használhatók.
AutoVisualizer elemént
A AutoVisualizer elem a .natvis fájl gyökércsomópontja, és tartalmazza a névteret xmlns: attribútumot.
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
.
.
</AutoVisualizer>
A AutoVisualizer elem tartalmazhat Type, HResult, UIVisualizerés CustomVisualizer al-elemeket.
Típus elem
Egy alapszintű Type a következő példához hasonlóan néz ki:
<Type Name="[fully qualified type name]">
<DisplayString Condition="[Boolean expression]">[Display value]</DisplayString>
<Expand>
...
</Expand>
</Type>
A Type elem a következőt adja meg:
Milyen típusú vizualizációt kell használni (a
Nameattribútumot).Az ilyen típusú objektumok értékének (a
DisplayStringelemnek) kell kinéznie.A típus tagjainak így kell kinéznie, amikor a felhasználó kibontja a típust egy változóablakban (a
Expandcsomópontban).
Template alapú osztályok
A Name elem Type attribútuma egy csillag * fogad el helyettesítő karakterként, amely sablonos osztálynevekhez használható.
Az alábbi példában ugyanazt a vizualizációt használjuk, függetlenül attól, hogy az objektum egy CAtlArray<int> vagy egy CAtlArray<float>. Ha van egy konkrét vizualizációs bejegyzés egy CAtlArray<float>-hoz, akkor az elsőbbséget élvez az általánossal szemben.
<Type Name="ATL::CAtlArray<*>">
<DisplayString>{{Count = {m_nSize}}}</DisplayString>
</Type>
A vizualizáció bejegyzésében szereplő sablonparaméterekre $T 1, $T 2 és így tovább makrók használatával hivatkozhat. Ezekre a makrókra példákat a Visual Studióval szállított .natvis fájlokban talál.
Vizualizációtípus egyeztetése
Ha egy vizualizációs bejegyzés ellenőrzése sikertelen, a rendszer a következő elérhető vizualizációt használja.
Örökölhető attribútum
Az opcionális Inheritable attribútum azt határozza meg, hogy a vizualizáció csak alaptípusra, vagy alaptípusra és minden származtatott típusra vonatkozik-e. A Inheritable alapértelmezett értéke true.
A következő példában a vizualizáció csak a BaseClass típusra vonatkozik:
<Type Name="Namespace::BaseClass" Inheritable="false">
<DisplayString>{{Count = {m_nSize}}}</DisplayString>
</Type>
Prioritás attribútum
Az opcionális Priority attribútum határozza meg a másodlagos definíciók használatának sorrendjét, ha egy definíció nem elemezhető. A Priority lehetséges értékei a következők: Low, MediumLow,Medium, MediumHighés High. Az alapértelmezett érték a Medium. A Priority attribútum csak ugyanazon .natvis fájlon belül különbözteti meg a prioritásokat.
Az alábbi példa először a 2015-ös STL-nek megfelelő bejegyzést elemzi. Ha ez nem sikerül értelmezni, akkor az STL 2013-as verziójának alternatív bejegyzését használja:
<!-- 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>
Nem kötelező attribútum
Bármely csomóponton elhelyezhet Optional attribútumot. Ha egy választható csomóponton belüli alexpresszió nem elemezhető, a hibakereső figyelmen kívül hagyja ezt a csomópontot, de alkalmazza a többi Type szabályt. Az alábbi típusban a [State] nem választható, de [Exception] nem kötelező. Ha MyNamespace::MyClass _M_exceptionHoldernevű mezővel rendelkezik, akkor a [State] csomópont és a [Exception] csomópont is megjelenik, de ha nincs _M_exceptionHolder mező, csak a [State] csomópont jelenik meg.
<Type Name="MyNamespace::MyClass">
<Expand>
<Item Name="[State]">_M_State</Item>
<Item Name="[Exception]" Optional="true">_M_exceptionHolder</Item>
</Expand>
</Type>
Feltétel attribútum
Az opcionális Condition attribútum számos vizualizációs elemhez elérhető, és meghatározza, hogy mikor érdemes vizualizációs szabályt használni. Ha a feltételattribútumban lévő kifejezés false, a vizualizációs szabály nem érvényes. Ha true értéket ad vissza, vagy nincs Condition attribútum, akkor a vizualizáció alkalmazható. Ezt az attribútumot használhatja az if-else logikához a vizualizáció bejegyzéseiben.
Az alábbi vizualizáció például két DisplayString elemet biztosít egy intelligens mutatótípushoz. Ha a _Myptr tag üres, az első DisplayString elem állapota true, így az űrlap megjelenik. Ha a _Myptr tag nem üres, a feltétel a következő lesz false, és megjelenik a második DisplayString elem.
<Type Name="std::auto_ptr<*>">
<DisplayString Condition="_Myptr == 0">empty</DisplayString>
<DisplayString>auto_ptr {*_Myptr}</DisplayString>
<Expand>
<ExpandedItem>_Myptr</ExpandedItem>
</Expand>
</Type>
IncludeView és ExcludeView attribútumok
A IncludeView és ExcludeView attribútumok adott nézetekben megjelenítendő vagy nem megjelenítendő elemeket határoznak meg. A std::vectorkövetkező Natvis-specifikációjában például a simple nézet nem jeleníti meg a [size] és [capacity] elemeket.
<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>
A IncludeView és az ExcludeView attribútumokat a típusok és az egyes tagok esetében használhatja.
Verzióelem
A Version elem egy adott modulra és verzióra vonatkozó vizualizációs bejegyzésre terjed ki. A Version elem segít elkerülni a névütközéseket, csökkenti a véletlen eltéréseket, és lehetővé teszi a különböző típusú verziók különböző vizualizációit.
Ha egy különböző modulok által használt közös fejlécfájl definiál egy típust, a verziószámozott vizualizáció csak akkor jelenik meg, ha a típus a megadott modulverzióban található.
Az alábbi példában a vizualizáció csak a DirectUI::Border 1.0-tól 1.5-ös verzióig található Windows.UI.Xaml.dll típusra alkalmazható.
<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>
Nincs szükség mindkettőre, Min-ra és Max-re. Nem kötelező attribútumok. A helyettesítő karakterek nem támogatottak.
A Name attribútum formátuma filename.ext, például hello.exe vagy some.dll. Nem engedélyezettek az elérési útnevek.
DisplayString elem
A DisplayString elem egy változó értékeként megjelenítendő sztringet határoz meg. Tetszőleges karaktersorozatokat fogad el, amelyek kifejezésekkel vannak vegyítve. A kapcsos zárójeleken belüli minden elem kifejezésként van értelmezve. Például a következő DisplayString bejegyzés:
<Type Name="CPoint">
<DisplayString>{{x={x} y={y}}}</DisplayString>
</Type>
Azt jelenti, hogy a CPoint típusú változók ilyen formában jelennek meg:
A DisplayString kifejezésben a x és y, amelyek a CPointtagjai, kapcsos zárójelek között vannak, így az értékek kiértékelése történik. A példa azt is bemutatja, hogyan kerülheti el a kapcsos kapcsos zárójeleket dupla kapcsos zárójelek ({{ vagy }}) használatával.
Jegyzet
A DisplayString elem az egyetlen elem, amely tetszőleges sztringeket és kapcsos zárójelek szintaxisát fogadja el. Minden más vizualizációs elem csak a hibakereső által kiértékelhető kifejezéseket fogadja el.
StringView elem
A StringView elem meghatároz egy értéket, amelyet a hibakereső elküldhet a beépített szövegábrázolónak. Például a ATL::CStringT típushoz a következő vizualizációt adja meg:
<Type Name="ATL::CStringT<wchar_t,*>">
<DisplayString>{m_pszData,su}</DisplayString>
</Type>
A CStringT objektum az alábbi példához hasonló változóablakban jelenik meg:
Egy StringView elem hozzáadásával a hibakereső megjelenítheti az értéket szöveges vizualizációként.
<Type Name="ATL::CStringT<wchar_t,*>">
<DisplayString>{m_pszData,su}</DisplayString>
<StringView>m_pszData,su</StringView>
</Type>
A hibakeresés során kiválaszthatja a változó melletti nagyító ikont, majd a Szövegábrázoló lehetőséget választva megjelenítheti azt a sztringet, amelyre m_pszData mutat.
CStringT-adatok 
A {m_pszData,su} kifejezés tartalmaz egy C++ formátumkijelölőt, su, amely Unicode-sztringként jeleníti meg az értéket. További információkért lásd a C++ formátumjelölőit.
Az elem kibontása
Az opcionális Expand csomópont testre szabja a vizualizált típus gyermekeit, amikor egy változóablakban kibontja a típust. A Expand csomópont elfogad egy listát a gyermekelemeket meghatározó alcsomópontokról.
Ha egy
Expandcsomópont nincs megadva vizualizációs bejegyzésben, a gyermekek az alapértelmezett bővítési szabályokat használják.Ha egy
Expandcsomópont van megadva gyermekcsomópontok nélkül, a típus nem bontható ki a hibakereső ablakokban.
Elem bővítése
A Item elem a Expand csomópont legalapvetőbb és leggyakoribb eleme.
Item egyetlen gyermek elemet határoz meg. Egy CRect osztály például top, left, rightés bottom mezővel a következő vizualizációs bejegyzéssel rendelkezik:
<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>
A hibakereső ablakban a CRect típus az alábbi példához hasonlóan néz ki:
A hibakereső kiértékeli a Width és Height elemekben megadott kifejezéseket, és megjeleníti a változóablak Érték oszlopában lévő értékeket.
A hibakereső automatikusan létrehozza a [Nyers nézet] csomópontot minden egyéni bővítéshez. Az előző képernyőképen a kibontott [Nyers nézet] csomópont látható, hogy az objektum alapértelmezett nyers nézete miben különbözik a Natvis-vizualizációtól. Az alapértelmezett bővítés létrehoz egy részhalmazt az alaposztályhoz, és az alaposztály összes adattagját gyermekként listázza.
Jegyzet
Ha az elemelem kifejezése összetett típusra mutat, a Elem csomópont kibontható.
ArrayItems bővítő
A ArrayItems csomópont használatával a Visual Studio hibakeresője tömbként értelmezi a típust, és megjeleníti az egyes elemeket. A std::vector vizualizációja jó példa:
<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>
A std::vector az egyes elemeket jeleníti meg a változóablakban kibontva:
A ArrayItems csomópontnak a következővel kell rendelkeznie:
- Egy
Sizekifejezés (amelynek egész számra kell kiértékelnie) a hibakereső számára a tömb hosszának megértéséhez. - A
ValuePointerkifejezés, amely az első elemre mutat, és amelynek egy olyan elemtípust kell mutatnia, ami nem `void*`.
Az alsó korlátú tömb alapértelmezett értéke 0. Az érték felülbírálásához használjon LowerBound elemet. A Visual Studióval szállított .natvis fájlok példákkal rendelkeznek.
Jegyzet
Használhatja például []az vector[i] operátort bármely egydimenziós tömbvizualizációval, amely használjaArrayItems, még akkor is, ha maga a típus (például CATLArray) nem engedélyezi ezt az operátort.
Többdimenziós tömböket is megadhat. Ebben az esetben a hibakeresőnek valamivel több információra van szüksége a gyermekelemek megfelelő megjelenítéséhez:
<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>
-
Directionmegadja, hogy a tömb sor-fő vagy oszlopfősorrendben van-e. -
Ranka tömb rangját adja meg. - A
Sizeelem elfogadja az implicit$iparamétert, amelyet a dimenzióindexkel helyettesít a tömb hosszának megkereséséhez a dimenzióban.- Az előző példában a
_M_extent.M_base[0]kifejezésnek meg kell adnia a 0. dimenzió hosszát,_M_extent._M_base[1]az elsőt stb.
- Az előző példában a
- A
LowerBounda tömb minden dimenziójának alsó határát adja meg. Többdimenziós tömbök esetén megadhat egy kifejezést, amely az implicit$iparamétert használja. A$iparaméter a dimenzióindexkel helyettesítve megkeresi a tömb alsó határát az adott dimenzióban.- Az előző példában az összes dimenzió 0-nál kezdődik. Ha azonban alsó határa volt
($i == 1) ? 1000 : 100, a 0. dimenzió 100-nál kezdődik, az első dimenzió pedig 1000-nél kezdődik.- , például
[100, 1000], [100, 1001], [100, 1002], ... [101, 1000], [101, 1001],...
- , például
- Az előző példában az összes dimenzió 0-nál kezdődik. Ha azonban alsó határa volt
Így néz ki egy kétdimenziós Concurrency::array objektum a hibakereső ablakban:
IndexListItems bővítmény
ArrayItems bővítést csak akkor használhatja, ha a tömbelemek egybefüggően vannak elhelyezve a memóriában. A hibakereső a mutató egyszerű növelésével jut el a következő elemhez. Ha módosítania kell az indexet az értékcsomóponton, használja IndexListItems csomópontokat. Íme egy vizualizáció egy IndexListItems csomóponttal:
<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>
A ArrayItems és a IndexListItems között az egyetlen különbség a ValueNode, amely az implicit paraméterrel az i$i elem teljes kifejezését várja.
Jegyzet
Használhatja például []az vector[i] operátort bármely egydimenziós tömbvizualizációval, amely használjaIndexListItems, még akkor is, ha maga a típus (például CATLArray) nem engedélyezi ezt az operátort.
LinkedListItems kibővítése
Ha a vizualizált típus egy csatolt listát jelöl, a hibakereső megjelenítheti gyermekeit egy LinkedListItems csomópont használatával. A CAtlList típus alábbi vizualizációja LinkedListItemshasznál:
<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>
A Size elem a lista hosszára hivatkozik.
HeadPointer az első elemre mutat, NextPointer a következő elemre, ValueNode pedig az elem értékére hivatkozik.
A hibakereső a NextPointer csomópontelem kontextusában értékeli ki a ValueNode és LinkedListItems kifejezéseket, nem pedig a szülőlista típusát. Az előző példában CAtlList rendelkezik egy CNode osztálysal (atlcoll.htalálható), amely a csatolt lista csomópontja.
m_pNext és m_element az adott CNode osztály mezői, nem pedig a CAtlList osztályhoz tartoznak.
ValueNode üresen hagyható, vagy this hivatkozhat magára a LinkedListItems csomópontra.
CustomListItems bővítmény
A CustomListItems bővítéssel egyéni logikát írhat egy adatstruktúra, például egy kivonatoló bejárásához. A CustomListItems használatával olyan adatstruktúrákat jeleníthet meg, amelyek C++ kifejezéseket használhatnak minden kiértékeléshez, de nem illeszkednek a ArrayItems, IndexListItemsvagy LinkedListItemsformázásához.
A Exec használatával kódot hajthat végre egy CustomListItems bővítőben a bővítőben definiált változók és objektumok használatával. Logikai operátorokat, számtani operátorokat és hozzárendelési operátorokat használhat Exec. A Exec nem használható függvények kiértékelésére, kivéve hibakereső belső függvényeket, a C++ kifejezésértékelő támogatja.
A CAtlMap alábbi vizualizációja kiváló példa az CustomListItems megfelelő használatára.
<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>
TreeItems bővítő
Ha a vizualizált típus egy fát jelöl, a hibakereső képes bejárni a fát, és egy TreeItems csomópont használatával megjeleníteni annak gyerekeit. A std::map típus vizualizációja egy TreeItems csomópont használatával:
<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>
A szintaxis hasonló a LinkedListItems csomóponthoz.
LeftPointer, RightPointerés ValueNode kiértékelése a facsomópont osztály kontextusában történik. A(z) ValueNode üresen hagyható, vagy használható a(z) this a(z) TreeItems csomópont önmagára való hivatkozásra.
ExpandItem bővítmény
A ExpandedItem elem összesített gyermeknézetet hoz létre az alaposztályok vagy adattagok tulajdonságainak megjelenítésével, mintha a vizualizált típusú gyermekek lennének. A hibakereső kiértékeli a megadott kifejezést, és hozzáfűzi az eredmény gyermekcsomópontjait a vizualizált típus gyermeklistájához.
Az intelligens mutató típusa például auto_ptr<vector<int>> általában a következőképpen jelenik meg:
A vektor értékeinek megtekintéséhez két szintet kell részleteznie a változóablakban, és át kell haladnia a _Myptr tagon. Egy ExpandedItem elem hozzáadásával eltávolíthatja a _Myptr változót a hierarchiából, és közvetlenül megtekintheti a vektorelemeket:
<Type Name="std::auto_ptr<*>">
<DisplayString>auto_ptr {*_Myptr}</DisplayString>
<Expand>
<ExpandedItem>_Myptr</ExpandedItem>
</Expand>
</Type>
Az alábbi példa bemutatja, hogyan összesítheti a tulajdonságokat az alaposztályból egy származtatott osztályban. Tegyük fel, hogy a CPanel osztály a CFrameworkElementszármazik. Az alap CFrameworkElement osztályból származó tulajdonságok ismétlése helyett a ExpandedItem csomópontvizualizáció hozzáfűzi ezeket a tulajdonságokat a CPanel osztály gyermeklistájához.
<Type Name="CPanel">
<DisplayString>{{Name = {*(m_pstrName)}}}</DisplayString>
<Expand>
<Item Name="IsItemsHost">(bool)m_bItemsHost</Item>
<ExpandedItem>*(CFrameworkElement*)this,nd</ExpandedItem>
</Expand>
</Type>
Itt a nd formátumjelölőre van szükség, amely kikapcsolja a származtatott osztályhoz tartozó vizualizációk egyezését. Ellenkező esetben a *(CFrameworkElement*)this kifejezés miatt a CPanel vizualizáció újra alkalmazva lesz, mert az alapértelmezett vizualizációtípus-egyeztetési szabályok a legmegfelelőbbnek tartják. A nd formátumjelölő használatával utasíthatja a hibakeresőt az alaposztály vizualizációjának használatára, vagy az alapértelmezett bővítésre, ha az alaposztály nem rendelkezik vizualizációval.
Szintetikus objektumbővítés
Míg a ExpandedItem elem a hierarchiák kiiktatásával nyújt laposabb nézetet az adatokról, a Synthetic csomópont az ellenkezőjét teszi. Lehetővé teszi egy olyan mesterséges gyermekelem létrehozását, amely nem egy kifejezés eredménye. A mesterséges elem saját gyermekelemekkel rendelkezhet. Az alábbi példában a Concurrency::array típus vizualizációja egy Synthetic csomópontot használ a felhasználónak szóló diagnosztikai üzenet megjelenítéséhez:
<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>
Belső bővítés
Egyéni belső függvény, amely egy kifejezésből hívható meg. A <Intrinsic> elemet egy hibakereső összetevőnek kell kísérnie, amely az IDkmIntrinsicFunctionEvaluator140 interfészen keresztül valósítja meg a függvényt. Az egyéni belső függvények implementálásával kapcsolatos további információkért lásd: NatVis egyéni belső függvény implementálása.
<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 elem
A HResult elem segítségével testre szabhatja az HRESULT megjelenített információkat a hibakereső ablakokban. A HRValue elemnek tartalmaznia kell a testre szabandó HRESULT 32 bites értékét. A HRDescription elem tartalmazza a hibakereső ablakban megjelenítendő információkat.
<HResult Name="MY_E_COLLECTION_NOELEMENTS">
<HRValue>0xABC0123</HRValue>
<HRDescription>No elements in the collection.</HRDescription>
</HResult>
UIVisualizer elemént
Egy UIVisualizer elem regisztrál egy grafikus vizualizációs beépülő modult a hibakeresőben. A grafikus vizualizációk létrehoznak egy párbeszédpanelt vagy más felületet, amely egy változót vagy objektumot az adattípusának megfelelő módon jelenít meg. A visualizációs beépülő modult VSPackageformájában kell elkészíteni, és közzé kell tennie egy olyan szolgáltatást, amelyet a hibakereső felhasználhat. A .natvis fájl tartalmazza a beépülő modul regisztrációs adatait, például a nevét, a közzétett szolgáltatás globálisan egyedi azonosítóját (GUID) és a megjeleníthető típusokat.
Íme egy példa egy UIVisualizer-elemre:
<?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>
Egy
ServiceId-Idattribútumpár azonosítja aUIVisualizer. AServiceIdannak a szolgáltatásnak a GUID azonosítója, amelyet a vizualizációs csomag elérhetővé tesz.Idegy egyedi azonosító, amely megkülönbözteti a vizualizációkat, ha egy szolgáltatás több szolgáltatást is biztosít. Az előző példában ugyanaz a vizualizációs szolgáltatás két vizualizációt biztosít.A
MenuNameattribútum egy vizualizáció nevét határozza meg, amely a hibakereső nagyító ikonja melletti legördülő listában jelenik meg. Például:
A .natvis fájlban definiált összes típusnak explicit módon fel kell sorolnia a megjeleníthető felhasználói felületi vizualizációkat. A hibakereső összepárosítja a típusbejegyzésekben található vizualizátor hivatkozásokat a regisztrált vizualizátorokkal. A std::vector típus következő bejegyzése például az előző példában szereplő UIVisualizer-re hivatkozik.
<Type Name="std::vector<int,*>">
<UIVisualizer ServiceId="{5452AFEA-3DF6-46BB-9177-C0B08F318025}" Id="1" />
</Type>
A memóriabeli bitképek megtekintéséhez használt UIVisualizer bővítményben egy látható.
CustomVisualizer eleme
CustomVisualizer egy bővíthetőségi pont, amely egy VSIX-bővítményt határoz meg, amelyet a Visual Studio Code vizualizációinak vezérléséhez ír. A VSIX-bővítmények írásával kapcsolatos további információkért lásd a Visual Studio SDK.
Az egyéni vizualizációk írása sokkal több munka, mint egy XML Natvis-definíció, de nem korlátozza, hogy a Natvis mit tesz vagy mit nem támogat. Az egyéni vizualizációk hozzáférhetnek a hibakereső bővíthetőségi API-k teljes készletéhez, amelyek lekérdezhetik és módosíthatják a hibakeresési folyamatot, vagy kommunikálhatnak a Visual Studio más részeivel.
A Condition, IncludeViewés ExcludeView attribútumokat CustomVisualizer elemeken használhatja.
Korlátozások
A Natvis-testreszabások osztályokkal és struktúrákkal működnek, de nem típusdefiníciókkal.
A Natvis nem támogatja a vizualizációkat a primitív típusok (például int, ) boolés a primitív típusok mutatói esetében. Ebben a forgatókönyvben az egyik lehetőség a formátumkijelölő használata, a használati esetnek megfelelő. Ha például a double* mydoublearray-et használja a kódban, akkor a hibakereső Watch ablakában használhatja a tömbspecifikátort, például a mydoublearray, [100]kifejezést, amely az első 100 elemet jeleníti meg.