Natvis çerçevesini kullanarak hata ayıklayıcıda C++ nesnelerinin özel görünümlerini oluşturma
Visual Studio Natvis çerçevesi, yerel türlerin Locals ve Watch pencereleri gibi hata ayıklayıcı değişken pencerelerinde ve Data İpuçları'da görüntülenme biçimini özelleştirir. Natvis görselleştirmeleri, oluşturduğunuz türleri hata ayıklama sırasında daha görünür hale getirmenize yardımcı olabilir.
Natvis, Visual Studio'nun önceki sürümlerindeki autoexp.dat dosyasını XML söz dizimi, daha iyi tanılama, sürüm oluşturma ve birden çok dosya desteğiyle değiştirir.
Not
Natvis özelleştirmeleri sınıflarla ve yapılarla çalışır, ancak tür tanımlarıyla çalışmaz.
Natvis görselleştirmeleri
Natvis çerçevesini, geliştiricilerin hata ayıklama sırasında bunları daha kolay görebilmesi için oluşturduğunuz türler için görselleştirme kuralları oluşturmak için kullanırsınız.
Örneğin, aşağıdaki çizimde özel görselleştirme uygulanmadan hata ayıklayıcı penceresinde Windows::UI::XAML::Controls::TextBox türünde bir değişken gösterilmektedir.
Vurgulanan satır sınıfın Text
TextBox
özelliğini gösterir. Karmaşık sınıf hiyerarşisi bu özelliği bulmayı zorlaştırır. Hata ayıklayıcısı özel dize türünü nasıl yorumlayabileceğinizi bilmediğinden metin kutusunun içinde tutulan dizeyi göremezsiniz.
TextBox
Aynı şey, Natvis özel görselleştirici kuralları uygulandığında değişken penceresinde çok daha basit görünür. Sınıfın önemli üyeleri birlikte görünür ve hata ayıklayıcı özel dize türünün temel dize değerini gösterir.
C++ projelerinde .natvis dosyalarını kullanma
Natvis görselleştirme kurallarını belirtmek için .natvis dosyalarını kullanır. .natvis dosyası, .natvis uzantısına sahip bir XML dosyasıdır. Natvis şeması VS Installation Folder>\Xml\Schemas\1033\natvis.xsd içinde <tanımlanır.
.natvis dosyasının temel yapısı, görselleştirme girdilerini temsil eden bir veya daha fazla Type
öğedir. Her Type
öğenin tam adı özniteliğinde Name
belirtilir.
<?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, VS Yükleme Klasörü>\Common7\Packages\Debugger\Visualizers klasöründe bazı .natvis dosyaları <sağlar. Bu dosyalar birçok yaygın tür için görselleştirme kurallarına sahiptir ve yeni türler için görselleştirme yazmak için örnek olarak kullanılabilir.
C++ projesine .natvis dosyası ekleme
Herhangi bir C++ projesine .natvis dosyası ekleyebilirsiniz.
Yeni bir .natvis dosyası eklemek için:
Çözüm Gezgini'da C++ proje düğümünü seçin ve Proje>Yeni öğe ekle'yi seçin veya projeye sağ tıklayıp Yeni öğe ekle'yi>seçin.
Tüm öğe şablonlarını görmüyorsanız Tüm Şablonları Göster'i seçin.
Yeni Öğe Ekle iletişim kutusunda Visual C++>Yardımcı Program>Hata Ayıklayıcısı görselleştirme dosyası (.natvis) öğesini seçin.
Dosyayı adlandırın ve Ekle'yi seçin.
Yeni dosya Çözüm Gezgini eklenir ve Visual Studio belge bölmesinde açılır.
Visual Studio hata ayıklayıcı C++ projelerinde .natvis dosyalarını otomatik olarak yükler ve varsayılan olarak, proje oluşturulduğunda bunları .pdb dosyasına da ekler. Oluşturulan uygulamada hata ayıklarsanız, proje açık olmasa bile hata ayıklayıcı .pdb dosyasından .natvis dosyasını yükler. .natvis dosyasının .pdb dosyasına eklenmesini istemiyorsanız, bunu yerleşik .pdb dosyasından dışlayabilirsiniz.
.natvis dosyasını .pdb'den dışlamak için:
Çözüm Gezgini.natvis dosyasını seçin ve Özellikler simgesini seçin veya dosyaya sağ tıklayıp Özellikler'i seçin.
Açılan listede, Derlemeden Dışlananlar'ın yanındaki ok listelenip Evet'i ve ardından Tamam'ı seçin.
Not
Yürütülebilir projelerde hata ayıklamak için çözüm öğelerini kullanarak kullanılabilir C++ projesi olmadığından .pdb'de olmayan .natvis dosyalarını ekleyin.
Not
.pdb'den yüklenen Natvis kuralları yalnızca .pdb'nin başvurduğu modüllerdeki türlere uygulanır. Örneğin, Module1.pdb adlı bir tür için Natvis girdisine sahipse, yalnızca Module1.dll sınıfı için Test
geçerlidir.Test
Başka bir modül de adlı Test
bir sınıf tanımlarsa Module1.pdb Natvis girdisi buna uygulanmaz.
VSIX paketi aracılığıyla bir .natvis dosyası yüklemek ve kaydetmek için:
VSIX paketi .natvis dosyalarını yükleyebilir ve kaydedebilir. Nerede yüklendiklerine bakılmaksızın, tüm kayıtlı .natvis dosyaları hata ayıklama sırasında otomatik olarak alınır.
.natvis dosyasını VSIX paketine ekleyin. Örneğin, aşağıdaki proje dosyası için:
<?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>
.natvis dosyasını source.extension.vsixmanifest dosyasına kaydedin:
<?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 dosya konumları
.natvis dosyalarını birden çok proje için uygulanmasını istiyorsanız, kullanıcı dizininize veya bir sistem dizinine ekleyebilirsiniz.
.natvis dosyaları aşağıdaki sırayla değerlendirilir:
Yüklenen projede aynı ada sahip bir dosya olmadığı sürece, hata ayıkladığınız bir .pdb'ye eklenmiş tüm .natvis dosyaları.
Yüklü bir C++ projesinde veya üst düzey çözümde bulunan tüm .natvis dosyaları. Bu grup, sınıf kitaplıkları dahil olmak üzere tüm yüklü C++ projelerini içerir, ancak diğer dillerdeki projeleri içermez.
VSIX paketi aracılığıyla yüklenen ve kaydedilen tüm .natvis dosyaları.
- Kullanıcıya özgü Natvis dizini (örneğin, %USERPROFILE%\Documents\Visual Studio 2022\Visualizers).
- Kullanıcıya özgü Natvis dizini (örneğin, %USERPROFILE%\Documents\Visual Studio 2019\Visualizers).
- Sistem genelinde Natvis dizini (<Microsoft Visual Studio Yükleme Klasörü>\Common7\Packages\Debugger\Visualizers). Bu dizin, Visual Studio ile yüklenen .natvis dosyalarına sahiptir. Yönetici izinleriniz varsa bu dizine dosya ekleyebilirsiniz.
Hata ayıklarken .natvis dosyalarını değiştirme
IDE'deki bir .natvis dosyasını projesinde hata ayıklarken değiştirebilirsiniz. Dosyayı hata ayıkladığınız Visual Studio örneğinde açın, değiştirin ve kaydedin. Dosya kaydedilir kaydedilmez, Watch ve Locals pencereleri değişikliği yansıtacak şekilde güncelleştirilir.
Ayrıca hata ayıkladığınız bir çözümde .natvis dosyaları ekleyebilir veya silebilirsiniz ve Visual Studio ilgili görselleştirmeleri ekler veya kaldırır.
Hata ayıklarken .pdb dosyalarına eklenmiş .natvis dosyalarını güncelleştiremezsiniz.
.natvis dosyasını Visual Studio dışında değiştirirseniz, değişiklikler otomatik olarak geçerli olmaz. Hata ayıklayıcı pencerelerini güncelleştirmek için, Anlık penceresinde .natvisreload komutunu yeniden değerlendirebilirsiniz. Ardından değişiklikler hata ayıklama oturumunu yeniden başlatmadan geçerlilik kazanır.
.natvis dosyasını daha yeni bir sürüme yükseltmek için .natvisreload komutunu da kullanın. Örneğin, .natvis dosyası kaynak denetiminde denetlenebilir ve başka birinin yaptığı son değişiklikleri almak isteyebilirsiniz.
İfadeler ve biçimlendirme
Natvis görselleştirmeleri, görüntülenecek veri öğelerini belirtmek için C++ ifadelerini kullanır. Hata ayıklayıcıdaki C++ ifadelerinin Bağlam işlecinde (C++) açıklanan iyileştirmelerine ve sınırlamalarına ek olarak, aşağıdakilere dikkat edin:
Natvis ifadeleri, geçerli yığın çerçevesi değil görselleştirilen nesne bağlamında değerlendirilir. Örneğin,
x
bir Natvis ifadesinde, geçerli işlevde x adlı yerel değişkene değil görselleştirilmekte olan nesnedeki x adlı alana başvurur. Natvis ifadelerindeki yerel değişkenlere erişemezsiniz, ancak genel değişkenlere erişebilirsiniz.Natvis ifadeleri işlev değerlendirmesine veya yan etkilere izin vermez. İşlev çağrıları ve atama işleçleri yoksayılır. Hata ayıklayıcı iç işlevleri yan etkisiz olduğundan, diğer işlev çağrılarına izin verilmiyor olsa bile herhangi bir Natvis ifadesinden serbestçe çağrılabilir.
İfadenin nasıl görüntüleyebileceğinizi denetlemek için, C++'da Biçim tanımlayıcıları bölümünde açıklanan biçim tanımlayıcılarından herhangi birini kullanabilirsiniz. Girdi, ArrayItems genişletmesindeki ifade gibi
Size
Natvis tarafından dahili olarak kullanıldığında biçim tanımlayıcıları yoksayılır.
Not
Natvis belgesi XML olduğundan, ifadeleriniz doğrudan büyük, küçük veya shift işleçlerini kullanamaz. Hem öğe gövdesinde hem de koşul deyimlerinde bu karakterlerden kaçmalısınız. Örneğin:
\<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 görünümleri
Türleri farklı şekillerde görüntülemek için farklı Natvis görünümleri tanımlayabilirsiniz. Örneğin, adlı simple
basitleştirilmiş görünümü tanımlayan bir görselleştirme std::vector
aşağıda verilmiştir. DisplayString
ve ArrayItems
öğeleri varsayılan görünümde ve simple
görünümde gösterilirken [size]
ve [capacity]
öğeleri görünümde simple
gösterilmez.
<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>
Gözcü penceresinde, alternatif bir görünüm belirtmek için ,görünüm biçimi belirticisini kullanın. Basit görünüm vec, görünüm (basit) olarak görünür:
Natvis hataları
Hata ayıklayıcı bir görselleştirme girişinde hatalarla karşılaştığında bunları yoksayar. Türü ham biçiminde görüntüler veya başka bir uygun görselleştirme seçer. Hata ayıklayıcının bir görselleştirme girdisini neden yoksayabildiğini anlamak ve temel söz dizimini görmek ve hataları ayrıştırmak için Natvis tanılamasını kullanabilirsiniz.
Natvis tanılamasını açmak için:
- Araçlar>Seçenekleri (veya Hata Ayıklama>Seçenekleri) >Hata Ayıklama>Çıkış Penceresi altında, Natvis tanılama iletilerini (yalnızca C++) Hata, Uyarı veya Ayrıntılı olarak ayarlayın ve ardından Tamam'ı seçin.
Hatalar Çıkış penceresinde görüntülenir.
Natvis söz dizimi başvurusu
Natvis dosyasında aşağıdaki öğeler ve öznitelikler kullanılabilir.
AutoVisualizer öğesi
AutoVisualizer
öğesi .natvis dosyasının kök düğümüdür ve namespace xmlns:
özniteliğini içerir.
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
.
.
</AutoVisualizer>
AutoVisualizer
öğesi Type, HResult, UIVisualizer ve CustomVisualizer alt öğelerine sahip olabilir.
Tür öğesi
Temel Type
bilgiler şu örneğe benzer:
<Type Name="[fully qualified type name]">
<DisplayString Condition="[Boolean expression]">[Display value]</DisplayString>
<Expand>
...
</Expand>
</Type>
Type
öğesi aşağıdakileri belirtir:
Görselleştirmenin hangi tür için kullanılması gerekir (
Name
öznitelik).Bu türdeki bir nesnenin değerinin nasıl görünmesi gerektiği (
DisplayString
öğesi).Kullanıcı türü bir değişken penceresinde (
Expand
düğüm) genişlettiğinde türün üyeleri nasıl görünmelidir?
Şablonlu sınıflar
Name
öğesinin Type
özniteliği, şablonlu sınıf adları için kullanılabilecek joker karakter olarak bir yıldız işareti *
kabul eder.
Aşağıdaki örnekte, nesnenin veya CAtlArray<float>
öğesinin olması fark etmese de aynı görselleştirme kullanılmıştırCAtlArray<int>
. için belirli bir görselleştirme girişi CAtlArray<float>
varsa, genel girişe göre önceliklidir.
<Type Name="ATL::CAtlArray<*>">
<DisplayString>{{Count = {m_nSize}}}</DisplayString>
</Type>
$T 1, $T 2 vb. makroları kullanarak görselleştirme girdisindeki şablon parametrelerine başvurabilirsiniz. Bu makroların örneklerini bulmak için bkz . Visual Studio ile birlikte gelen .natvis dosyaları.
Görselleştirici türü eşleştirme
Görselleştirme girdisi doğrulanamıyorsa, bir sonraki kullanılabilir görselleştirme kullanılır.
Devralınabilir öznitelik
İsteğe bağlı Inheritable
öznitelik, görselleştirmenin yalnızca bir temel türe mi yoksa temel türe ve türetilmiş tüm türlere mi uygulandığını belirtir. Inheritable
için varsayılan değer true
değeridir.
Aşağıdaki örnekte görselleştirme yalnızca tür için BaseClass
geçerlidir:
<Type Name="Namespace::BaseClass" Inheritable="false">
<DisplayString>{{Count = {m_nSize}}}</DisplayString>
</Type>
Öncelik özniteliği
İsteğe bağlı Priority
öznitelik, bir tanım ayrıştırılamazsa alternatif tanımların kullanılacağı sırayı belirtir. olası değerleri Priority
şunlardır: Low
, MediumLow
,Medium
, MediumHigh
ve High
. Varsayılan değer şudur: Medium
. Priority
özniteliği yalnızca aynı .natvis dosyasındaki öncelikler arasında ayırt eder.
Aşağıdaki örnek ilk olarak 2015 STL ile eşleşen girişi ayrıştırmaktadır. Bu ayrıştırılamazsa, STL'nin 2013 sürümü için alternatif girişi kullanır:
<!-- 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>
İsteğe bağlı öznitelik
Herhangi bir düğüme öznitelik Optional
koyabilirsiniz. İsteğe bağlı bir düğüm içindeki bir alt ifade ayrıştırılamazsa, hata ayıklayıcı bu düğümü yoksayar, ancak kuralların geri kalanını Type
uygular. Aşağıdaki tür isteğe [State]
bağlı değildir, ancak [Exception]
isteğe bağlıdır. _M_exceptionHolder
adlı bir alanı varsa MyNamespace::MyClass
hem düğüm hem [Exception]
de [State]
düğüm görünür, ancak alan yoksa _M_exceptionHolder
yalnızca [State]
düğüm görüntülenir.
<Type Name="MyNamespace::MyClass">
<Expand>
<Item Name="[State]">_M_State</Item>
<Item Name="[Exception]" Optional="true">_M_exceptionHolder</Item>
</Expand>
</Type>
Condition özniteliği
İsteğe bağlı Condition
öznitelik birçok görselleştirme öğesi için kullanılabilir ve görselleştirme kuralının ne zaman kullanılacağını belirtir. condition özniteliği içindeki ifade olarak çözümlanırsa false
görselleştirme kuralı uygulanmaz. olarak değerlendirilirse true
veya özniteliği yoksa Condition
görselleştirme uygulanır. Görselleştirme girişlerindeki if-else mantığı için bu özniteliği kullanabilirsiniz.
Örneğin, aşağıdaki görselleştirmede akıllı işaretçi türü için iki DisplayString
öğe vardır. _Myptr
Üye boş olduğunda, formun görüntülenmesi için ilk DisplayString
öğenin koşulu olarak true
çözülür. _Myptr
Üye boş olmadığında koşul olarak değerlendirilir false
ve ikinci DisplayString
öğe görüntülenir.
<Type Name="std::auto_ptr<*>">
<DisplayString Condition="_Myptr == 0">empty</DisplayString>
<DisplayString>auto_ptr {*_Myptr}</DisplayString>
<Expand>
<ExpandedItem>_Myptr</ExpandedItem>
</Expand>
</Type>
IncludeView ve ExcludeView öznitelikleri
IncludeView
ve ExcludeView
öznitelikleri, belirli görünümlerde görüntülenecek veya görüntülenmeyen öğeleri belirtir. Örneğin, aşağıdaki Natvis belirtiminde std::vector
simple
görünüm ve [capacity]
öğelerini görüntülemez[size]
.
<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>
ve ExcludeView
özniteliklerini türlerde ve tek tek üyeler üzerinde kullanabilirsinizIncludeView
.
Sürüm öğesi
öğesi, Version
görselleştirme girişinin kapsamını belirli bir modüle ve sürüme göre daraltıyor. Version
öğesi ad çakışmalarını önlemeye yardımcı olur, yanlışlıkla uyuşmazlıkları azaltır ve farklı tür sürümleri için farklı görselleştirmelere izin verir.
Farklı modüller tarafından kullanılan ortak bir üst bilgi dosyası bir tür tanımlarsa, sürüme alınan görselleştirme yalnızca tür belirtilen modül sürümünde olduğunda görüntülenir.
Aşağıdaki örnekte görselleştirme yalnızca sürüm 1.0'dan 1.5'e kadar olan sürümde Windows.UI.Xaml.dll
bulunan tür için DirectUI::Border
geçerlidir.
<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>
Hem hem de Min
Max
gerekmez. Bunlar isteğe bağlı özniteliklerdir. Joker karakter desteklenmez.
Name
özniteliği, hello.exe veya some.dll gibi filename.ext biçimindedir. Yol adlara izin verilmez.
DisplayString öğesi
öğesi, DisplayString
bir değişkenin değeri olarak gösterilecek bir dize belirtir. İfadelerle karıştırılmış rastgele dizeleri kabul eder. Küme ayraçlarının içindeki her şey bir ifade olarak yorumlanır. Örneğin, aşağıdaki DisplayString
girdi:
<Type Name="CPoint">
<DisplayString>{{x={x} y={y}}}</DisplayString>
</Type>
Türündeki değişkenlerin CPoint
şu şekilde gösterildiği anlamına gelir:
ve ifadesinde DisplayString
, x
y
öğesinin CPoint
üyesi olan küme ayraçlarının içindedir, bu nedenle değerleri değerlendirilir. Örnek ayrıca çift küme ayracı ( {{
veya }}
) kullanarak küme ayracından nasıl kaçabileceğinizi de gösterir.
Not
DisplayString
öğesi, rastgele dizeleri ve küme ayracı söz dizimini kabul eden tek öğedir. Diğer tüm görselleştirme öğeleri yalnızca hata ayıklayıcının değerlendirebileceği ifadeleri kabul eder.
StringView öğesi
öğesi, StringView
hata ayıklayıcının yerleşik metin görselleştiricisine gönderebileceği bir değer tanımlar. Örneğin, türü için aşağıdaki görselleştirme göz önünde bulundurulduğunda ATL::CStringT
:
<Type Name="ATL::CStringT<wchar_t,*>">
<DisplayString>{m_pszData,su}</DisplayString>
</Type>
CStringT
nesnesi şu örneğe benzer bir değişken penceresinde görüntülenir:
Öğe StringView
eklemek hata ayıklayıcıya değeri metin görselleştirmesi olarak görüntüleyebileceğini bildirir.
<Type Name="ATL::CStringT<wchar_t,*>">
<DisplayString>{m_pszData,su}</DisplayString>
<StringView>m_pszData,su</StringView>
</Type>
Hata ayıklama sırasında değişkenin yanındaki büyüteç simgesini ve ardından Metin Görselleştiricisi'ni seçerek işaret m_pszData dizeyi görüntüleyebilirsiniz.
İfade {m_pszData,su}
, değeri Unicode dizesi olarak görüntülemek için bir C++ biçim belirtici su içerir. Daha fazla bilgi için bkz . C++ dilinde biçim tanımlayıcıları.
Öğeyi genişlet
İsteğe bağlı Expand
düğüm, türü değişken penceresinde genişlettiğinizde görselleştirilmiş bir türün alt öğelerini özelleştirir. Düğüm, Expand
alt öğeleri tanımlayan alt düğümlerin listesini kabul eder.
Görselleştirme girişinde bir
Expand
düğüm belirtilmezse, alt öğeler varsayılan genişletme kurallarını kullanır.Altında alt düğüm olmadan bir
Expand
düğüm belirtilirse, tür hata ayıklayıcı pencerelerinde genişletilemez.
Öğe genişletme
Item
öğesi bir düğümdeki en temel ve ortak öğedirExpand
. Item
tek bir alt öğe tanımlar. Örneğin, , , left
right
ve bottom
alanlarına top
sahip bir CRect
sınıf aşağıdaki görselleştirme girdisine sahiptir:
<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>
Hata ayıklayıcı penceresinde, CRect
tür şu örneğe benzer:
Hata ayıklayıcısı ve öğelerinde Width
belirtilen ifadeleri değerlendirir ve değerleri değişken penceresinin Değer sütununda Height
gösterir.
Hata ayıklayıcı her özel genişletme için otomatik olarak [Raw View] düğümünü oluşturur. Yukarıdaki ekran görüntüsü, nesnenin varsayılan ham görünümünün Natvis görselleştirmesinden nasıl farklı olduğunu göstermek için genişletilmiş [Ham Görünüm] düğümünü görüntüler. Varsayılan genişletme, temel sınıf için bir alt ağaç oluşturur ve temel sınıfın tüm veri üyelerini alt öğe olarak listeler.
Not
Öğe öğesinin ifadesi karmaşık bir türe işaret ederse, Öğe düğümünün kendisi genişletilebilir.
ArrayItems genişletmesi
ArrayItems
Visual Studio hata ayıklayıcısının türü bir dizi olarak yorumlamasını ve tek tek öğelerini görüntülemesini sağlamak için düğümü kullanın. için std::vector
görselleştirme iyi bir örnektir:
<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
, değişken penceresinde genişletildiğinde tek tek öğelerini gösterir:
Düğümde ArrayItems
aşağıdakiler olmalıdır:
Size
Hata ayıklayıcının dizinin uzunluğunu anlaması için bir ifade (bir tamsayı olarak değerlendirilmelidir).ValuePointer
İlk öğeye işaret eden bir ifade (olmayan bir öğe türününvoid*
işaretçisi olmalıdır).
Dizinin alt sınırındaki varsayılan değer 0'dır. Değeri geçersiz kılmak için bir LowerBound
öğe kullanın. Visual Studio ile birlikte gönderilen .natvis dosyalarının örnekleri vardır.
Not
örneğin vector[i]
işlecini, türün []
kendisi (örneğinCATLArray
) bu işlecine izin vermese bile kullanan tek boyutlu dizi görselleştirmeleriyle ArrayItems
kullanabilirsiniz.
Çok boyutlu diziler de belirtebilirsiniz. Bu durumda, alt öğeleri düzgün bir şekilde görüntülemek için hata ayıklayıcı biraz daha fazla bilgiye ihtiyaç duyar:
<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>
Direction
dizinin satır-birincil veya sütun-ana sıralı olup olmadığını belirtir.Rank
dizinin derecesini belirtir.Size
öğesi, bu boyuttaki dizinin uzunluğunu bulmak için boyut diziniyle değiştirdiği örtük$i
parametreyi kabul eder.- Önceki örnekte ifade
_M_extent.M_base[0]
, 0. boyutun uzunluğunu,_M_extent._M_base[1]
ilkini vb. vermelidir.
- Önceki örnekte ifade
- ,
LowerBound
dizinin her boyutunun alt sınırlarını belirtir. Çok boyutlu diziler için örtük$i
parametresini kullanan bir ifade belirtebilirsiniz. Parametresi,$i
bu boyuttaki dizinin alt sınırlarını bulmak için boyut diziniyle değiştirilir.- Önceki örnekte tüm boyutlar 0'da başlayacaktır. Ancak alt sınıra sahipseniz
($i == 1) ? 1000 : 100
, 0. boyut 100'de başlar ve ilk boyut 1000'de başlar.- Gibi
[100, 1000], [100, 1001], [100, 1002], ... [101, 1000], [101, 1001],...
- Gibi
- Önceki örnekte tüm boyutlar 0'da başlayacaktır. Ancak alt sınıra sahipseniz
Hata ayıklayıcı penceresinde iki boyutlu Concurrency::array
bir nesne şöyle görünür:
IndexListItems genişletmesi
Genişletmeyi yalnızca dizi öğeleri bellekte bitişik olarak yerleştirilmişse kullanabilirsiniz ArrayItems
. Hata ayıklayıcı, işaretçisini artırarak sonraki öğeye geçer. Dizini değer düğümüne yönlendirmeniz gerekiyorsa düğümleri kullanın IndexListItems
. Düğüm içeren bir görselleştirme aşağıdadır 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>
ile arasındaki ArrayItems
tek fark, örtük $i
parametresiyle i. öğesine tam ifadeyi bekleyen değeridirValueNode
.IndexListItems
Not
örneğin vector[i]
işlecini, türün []
kendisi (örneğinCATLArray
) bu işlecine izin vermese bile kullanan tek boyutlu dizi görselleştirmeleriyle IndexListItems
kullanabilirsiniz.
LinkedListItems genişletmesi
Görselleştirilmiş tür bağlantılı bir listeyi temsil ederse, hata ayıklayıcı bir LinkedListItems
düğüm kullanarak alt öğelerini görüntüleyebilir. Türü için aşağıdaki görselleştirmede CAtlList
kullanılır 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>
Size
öğesi listenin uzunluğuna başvurur. HeadPointer
ilk öğeye işaret eder, NextPointer
sonraki öğeye ve ValueNode
öğenin değerine başvurur.
Hata ayıklayıcı, ve ValueNode
ifadelerini üst liste türü değil düğüm öğesi bağlamında LinkedListItems
değerlendirirNextPointer
. Yukarıdaki örnekte, CAtlList
bağlı listenin düğümü olan bir CNode
sınıfı (içinde atlcoll.h
bulunur) vardır. m_pNext
ve m_element
bu sınıfın CNode
alanlarıdır, sınıfın CAtlList
değil.
ValueNode
boş bırakılabilir veya düğümün LinkedListItems
kendisine başvurmak için kullanabilirsinizthis
.
CustomListItems genişletmesi
Genişletme, CustomListItems
karma tablo gibi bir veri yapısından geçiş yapmak için özel mantık yazmanızı sağlar. Değerlendirmeniz gereken her şey için C++ ifadelerini kullanabilen ancak , IndexListItems
veya LinkedListItems
için kalıba tam olarak uymayan veri yapılarını görselleştirmek için ArrayItems
kullanınCustomListItems
.
Genişletmede tanımlanan değişkenleri ve nesneleri kullanarak bir CustomListItems
genişletmenin içinde kod yürütmek için kullanabilirsinizExec
. ile Exec
mantıksal işleçler, aritmetik işleçler ve atama işleçleri kullanabilirsiniz. C++ ifade değerlendiricisi tarafından desteklenen hata ayıklayıcı iç işlevleri dışında işlevleri değerlendirmek için kullanamazsınızExec
.
için CAtlMap
aşağıdaki görselleştirici, uygun olan CustomListItems
mükemmel bir örnektir.
<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 genişletmesi
Görselleştirilmiş tür bir ağacı temsil ederse, hata ayıklayıcı bir TreeItems
düğüm kullanarak ağaçta gezinebilir ve alt öğelerini görüntüleyebilir. Düğüm kullanan TreeItems
türün görselleştirmesi std::map
aşağıdadır:
<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>
Söz dizimi düğüme LinkedListItems
benzer. LeftPointer
, RightPointer
ve ValueNode
ağaç düğümü sınıfı bağlamında değerlendirilir. ValueNode
boş bırakılabilir veya düğümün TreeItems
kendisine başvurmak için kullanılabilirthis
.
ExpandedItem genişletmesi
öğesi, ExpandedItem
temel sınıfların veya veri üyelerinin özelliklerini görselleştirilmiş türün alt öğeleriymiş gibi görüntüleyerek toplu bir alt görünüm oluşturur. Hata ayıklayıcı belirtilen ifadeyi değerlendirir ve sonucun alt düğümlerini görselleştirilmiş türün alt listesine ekler.
Örneğin, akıllı işaretçi türü auto_ptr<vector<int>>
genellikle şu şekilde görüntülenir:
Vektör değerlerini görmek için değişken penceresinde üyeden geçen iki düzeyin detayına _Myptr
gitmeniz gerekir. Bir ExpandedItem
öğe ekleyerek değişkeni hiyerarşiden ortadan kaldırıp _Myptr
vektör öğelerini doğrudan görüntüleyebilirsiniz:
<Type Name="std::auto_ptr<*>">
<DisplayString>auto_ptr {*_Myptr}</DisplayString>
<Expand>
<ExpandedItem>_Myptr</ExpandedItem>
</Expand>
</Type>
Aşağıdaki örnekte, türetilmiş bir sınıftaki temel sınıftan özelliklerin nasıl toplandığı gösterilmektedir. CPanel
sınıfının öğesinden CFrameworkElement
türetilmiş olduğunu varsayalım. Düğüm görselleştirmesi, temel CFrameworkElement
sınıftan gelen özellikleri yinelemek yerine bu ExpandedItem
özellikleri sınıfın CPanel
alt listesine ekler.
<Type Name="CPanel">
<DisplayString>{{Name = {*(m_pstrName)}}}</DisplayString>
<Expand>
<Item Name="IsItemsHost">(bool)m_bItemsHost</Item>
<ExpandedItem>*(CFrameworkElement*)this,nd</ExpandedItem>
</Expand>
</Type>
Türetilmiş sınıf için görselleştirme eşleştirmesini kapatan nd biçim tanımlayıcısı burada gereklidir. Aksi takdirde, varsayılan görselleştirme türü eşleştirme kuralları bunu en uygun kural olarak kabul ettiğinden ifade *(CFrameworkElement*)this
görselleştirmenin yeniden uygulanmasına neden CPanel
olur. Hata ayıklayıcıya temel sınıf görselleştirmesini kullanmasını bildirmek için nd biçim tanımlayıcısını veya temel sınıfın görselleştirmesi yoksa varsayılan genişletmeyi kullanın.
Yapay öğe genişletme
ExpandedItem
öğesi hiyerarşileri ortadan kaldırarak verilerin daha düz bir görünümünü sağlarken düğüm Synthetic
tam tersini yapar. İfadenin sonucu olmayan yapay bir alt öğe oluşturmanıza olanak tanır. Yapay öğe kendi alt öğelerine sahip olabilir. Aşağıdaki örnekte, türüne yönelik Concurrency::array
görselleştirme kullanıcıya tanılama iletisi göstermek için bir Synthetic
düğüm kullanır:
<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>
Instrinsic genişletme
bir ifadeden çağrılabilen özel bir iç işlev. Bir <Intrinsic>
öğeye, IDkmIntrinsicFunctionEvaluator140 arabirimi aracılığıyla işlevi uygulayan bir hata ayıklayıcısı bileşeni eşlik etmelidir.
<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 öğesi
öğesi, HResult
hata ayıklayıcı pencerelerinde HRESULT için gösterilen bilgileri özelleştirmenize olanak tanır. HRValue
öğesi, özelleştirilecek HRESULT değerinin 32 bit değerini içermelidir. HRDescription
öğesi, hata ayıklayıcı penceresinde gösterilecek bilgileri içerir.
<HResult Name="MY_E_COLLECTION_NOELEMENTS">
<HRValue>0xABC0123</HRValue>
<HRDescription>No elements in the collection.</HRDescription>
</HResult>
UIVisualizer öğesi
Öğe UIVisualizer
, bir grafik görselleştirici eklentisini hata ayıklayıcıya kaydeder. Grafik görselleştirici, değişken veya nesneyi veri türüyle tutarlı bir şekilde gösteren bir iletişim kutusu veya başka bir arabirim oluşturur. Görselleştirici eklentisi bir VSPackage olarak yazılmalıdır ve hata ayıklayıcının kullanabileceği bir hizmeti kullanıma sunmalıdır. .natvis dosyası eklentinin adı, kullanıma sunulan hizmetin genel benzersiz tanımlayıcısı (GUID) ve görselleştirebileceği türler gibi kayıt bilgilerini içerir.
UiVisualizer öğesinin bir örneği aşağıda verilmiştir:
<?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>
Öznitelik
ServiceId
-Id
çifti birUIVisualizer
tanımlar.ServiceId
, görselleştirici paketinin kullanıma sunmasının hizmet GUID değeridir.Id
, bir hizmet birden fazla hizmet sağlıyorsa görselleştiricileri birbirinden ayıran benzersiz bir tanımlayıcıdır. Yukarıdaki örnekte, aynı görselleştirici hizmeti iki görselleştirici sağlar.özniteliği,
MenuName
hata ayıklayıcıdaki büyüteç simgesinin yanındaki açılan listede görüntülenecek bir görselleştirici adı tanımlar. Örneğin:
.natvis dosyasında tanımlanan her tür, bunu görüntüleyebilen tüm UI görselleştiricilerini açıkça listelemelidir. Hata ayıklayıcı, tür girişlerindeki görselleştirici başvurularını kayıtlı görselleştiricilerle eşleştirir. Örneğin, yukarıdaki örnekte başvurusu için std::vector
UIVisualizer
aşağıdaki tür girdisi.
<Type Name="std::vector<int,*>">
<UIVisualizer ServiceId="{5452AFEA-3DF6-46BB-9177-C0B08F318025}" Id="1" />
</Type>
Bellek içi bit eşlemleri görüntülemek için kullanılan Image Watch uzantısında örneğini UIVisualizer
görebilirsiniz.
CustomVisualizer öğesi
CustomVisualizer
, Visual Studio Code'daki görselleştirmeleri denetlemek için yazdığınız VSIX uzantısını belirten bir genişletilebilirlik noktasıdır. VSIX uzantıları yazma hakkında daha fazla bilgi için bkz. Visual Studio SDK'sı.
Özel görselleştirici yazmak XML Natvis tanımından çok daha fazla iştir, ancak Natvis'in ne yaptığı veya desteklemediğiyle ilgili kısıtlamalardan kurtulmuş olursunuz. Özel görselleştiriciler, hata ayıklama işlemi sorgulayıp değiştirebilen veya Visual Studio'nun diğer bölümleriyle iletişim kurabilen hata ayıklayıcı genişletilebilirlik API'lerinin tamamına erişebilir.
Öğelerde Condition
, IncludeView
ve ExcludeView
özniteliklerini CustomVisualizer
kullanabilirsiniz.
Sınırlamalar
Natvis özelleştirmeleri sınıflarla ve yapılarla çalışır, ancak tür tanımlarıyla çalışmaz.
Natvis, ilkel türler (örneğin, int
, bool
) veya ilkel türlerin işaretçileri için görselleştiricileri desteklemez. Bu senaryoda, bir seçenek kullanım örneğiniz için uygun biçim belirticiyi kullanmaktır. Örneğin, kodunuzda kullanıyorsanız double* mydoublearray
, hata ayıklayıcının gözcü penceresinde ilk 100 öğeyi gösteren ifadesi mydoublearray, [100]
gibi bir dizi biçimi belirticisi kullanabilirsiniz.