Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu makalede, NatVis görselleştirmesinde özel bir iç işlev uygulama yönergeleri hakkında bilgi ediniyorsunuz. NatVis hakkında daha fazla bilgi için bkz. C++ nesnelerinin özel görünümlerini oluşturma.
Sözdizimi
NatVis dosyası, aşağıdaki söz dizimini kullanarak iç işlev tanımlayabilir:
<Intrinsic Name="Func" Expression="arg + 1">
<Parameter Name="arg" Type="int" />
</Intrinsic>
Tanım mevcut olduğunda, herhangi bir hata ayıklayıcısı ifadesi diğer işlevler gibi işlevi çağırabilir. Örneğin, önceki NatVis tanımını kullanarak Func(3) ifadesi 4 olarak değerlendirilir.
<Intrinsic> öğesi, diğer öğelerden önce dosya düzeyinde veya bir <Type> öğesinin içinde görüntülenebilir. bir <Type> içinde tanımlanan iç işlevler bu türdeki üye işlevlerini tanımlarken, <Type> dışında tanımlanan iç işlevler genel işlevleri tanımlar. Örneğin:
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="std::vector<*>">
<Intrinsic Name="size" Expression="_Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst" />
<Intrinsic Name="capacity" Expression="_Mypair._Myval2._Myend - _Mypair._Myval2._Myfirst" />
</Type>
<Intrinsic Name="LOWORD" Expression="arg & 0xFFFF">
<Parameter Name="arg" Type="unsigned int" />
</Intrinsic>
</AutoVisualizer>
Önceki örnekte, size() ve capacity()std::vector sınıfının üye işlevleri olarak tanımlanır, bu nedenle bir ifade vector.size()değerlendirdiğinde, aslında bir func-eval yerine vector._Mypair._Myval2._Mylast - vector._Mypair._Myval2._Myfirstdeğerlendirir.
Benzer şekilde LOWORD(0x12345678), func-eval olmadan da 0x5678döndürür.
Başka bir örnek için bkz. İç genişletme.
İç işlev kullanma yönergeleri
İç işlev kullanırken aşağıdaki yönergelere dikkat edin:
İç işlevler, PDB tanımlı işlevlerle veya birbirleriyle aşırı yüklenebilir.
İç işlev aynı ad ve bağımsız değişken listesiyle PDB tanımlı bir işlevle çakışırsa, iç işlev kazanır. Eşdeğer bir iç işlev varsa, PDB işlevini değerlendiremezsiniz.
Bir iç işlevin adresini alamazsınız; sadece çağırabilirsiniz.
İç üye işlevlerinin bir ifadede değerlendirilebilmesi için ilgili türün varsayılan görünümüne ait olması gerekir. Örneğin,
IncludeViewkısıtlaması olan bir tür girdisi iç işlev belirtmeyebilir.İç işlevler, NatVis ifadeleri de dahil olmak üzere herhangi bir ifadeden çağrılabilir. İç işlevler de birbirini çağırabilir. Ancak özyineleme kullanan iç işlevler şu anda desteklenmemektedir. Mesela:
<!-- OK --> <Intrinsic Name="Func2" Expression="this->Func3(arg + 1)"> <Parameter Name="arg" Type="int" /> </Intrinsic> <Intrinsic Name="Func3" Expression="arg + 1"> <Parameter Name="arg" Type="int"/> </Intrinsic> <!-- Unsupported --> <Intrinsic Name="Func2" Expression="this->Func3(arg + 1)"> <Parameter Name="arg" Type="int" /> </Intrinsic> <Intrinsic Name="Func3" Expression="Func2(arg + 1)"> <Parameter Name="arg" Type="int"/> </Intrinsic> <!-- Also unsupported--> <Intrinsic Name="Fib" Expression="(n <= 1) ? 1 : Fib(n - 1) + Fib(n - 2)"> <Parameter Name="n" Type="int"/> </Intrinsic>Varsayılan olarak, iç işlevlerin yan etkisiz olduğu varsayılır. Yani, yan etkilere izin verilmeyen bağlamlarda çağrılabilirler ve uygulama ifadesinin yan etkiler içermesine izin verilmez.
Tanım, bildirimde
SideEffectözniteliğini belirterek bu davranışı geçersiz kılabilir. İşlev yan etkilere sahip olarak işaretlenmişse, uygulama ifadesindeki yan etkilere izin verilir. Ancak, işlevi yan etkilerin yasaklandığı bağlamlarda çağırmaya artık izin verilmez.İki iç işlevin tanımları birbiriyle çakıştığında (aynı ad, aynı imza), sonuncu kazanır (aynı dosya içinde).
Farklı dosyalar içinde, yüksek öncelikli dosyadaki örnek kazanır (proje, kullanıcı dizininden daha yüksek, kullanıcı dizini de yükleme dizininden daha yüksektir). Yüksek öncelikli bir tanım ayrıştırılmayan bir ifade içeriyorsa, bu tanım yoksayılır ve bunun yerine sonraki en yüksek öncelikli tanım kullanılır.
İç işlevi uygulama yönergeleri
İç işlevler iki olası uygulama şeklini destekler:
İfade tabanlı
NatVis dosyası, işlevin dönüş değerini değerlendiren bir ifade tanımlar. İfade,
<Parameter>öğeleri olarak tanımlanan ve kendisine aktarılan bağımsız değişkenleri kullanabilir. Bir sınıf içinde tanımlanan işlevlerin de "örnek" işlevler olduğu varsayılır ve "bu" işaretçisine de erişebilir.Uzantı tabanlı
NatVis dosyası, işlevi gerçekten değerlendirmek için hata ayıklayıcı uzantısını çağırmaya yönelik yönergeler sağlar. Hata ayıklayıcı uzantısı Concord API'sine tam erişime sahiptir ve NatVis ifadesinde mümkün olmayan görevleri gerçekleştirebilir.
Uzantı tabanlı bir uygulama sağlamak için, <Intrinsic> öğesi Expression özniteliğini atlamalıdır ve bunun yerine, aşağıdaki örnekte gösterildiği gibi SourceId, LanguageId, Idve ReturnType öznitelikleri sağlamalıdır:
<Intrinsic Name="MyFunc" SourceId="a665fa54-6e7d-480e-a80b-1fc1202e9646" LanguageId="3a12d0b7-c26c-11d0-b442-00a0244a1dd2" Id="1000" ReturnType="double">
<Parameter Type="int" />
<Parameter Type="int" />
<Parameter Type="int" />
</Intrinsic>
İşlevi uygulamak için hata ayıklayıcısı uzantısının NatVis dosyasındaki <Intrinsic> öğesinin karşılık gelen değerleriyle eşleşen LanguageId ve SourceId filtrelerini kullanarak IDkmIntrinsicFunctionEvaluator140 arabirimini uygulaması gerekir. İşlev çağrıldığında çağrı bileşenin Execute() yöntemine çevrilir:
STDMETHOD(Execute)(
_In_ Evaluation::IL::DkmILExecuteIntrinsic* pExecuteIntrinsic,
_In_ Evaluation::DkmILContext* pILContext,
_In_ Evaluation::IL::DkmCompiledILInspectionQuery* pInspectionQuery,
_In_ const DkmArray<Evaluation::IL::DkmILEvaluationResult*>& Arguments,
_In_opt_ DkmReadOnlyCollection<Evaluation::DkmCompiledInspectionQuery*>* pSubroutines,
_Out_ DkmArray<Evaluation::IL::DkmILEvaluationResult*>* pResults,
_Out_ Evaluation::IL::DkmILFailureReason* pFailureReason
);
Bileşen, Arguments bağımsız değişkeni aracılığıyla her bir bağımsız değişkenin baytlarını alır. Söz konusu işlev bir üye işlevse, önce this işaretçisi, ardından açık bağımsız değişkenler gelir. Bileşen, dönüş değerinin baytlarını depolayarak pResultsiçinde tek öğeli bir dizi ayırarak sonucu döndürmelidir.
İşlevleri uygulamak için aşağıdaki yönergeleri kullanın:
İki uygulama biçimi "karıştırmak ve eşleştirmek" yasal değildir. Yani, hem ifade hem de kaynak kimliği ekleyemezsiniz.
İfade tabanlı bir uygulama için dönüş türü belirtmeye izin verilir, ancak gerekli değildir. Eğer bir dönüş türü belirtilmişse, ifadenin dönüş türü tam olarak onunla eşleşmelidir (örtük dönüştürmeye izin verilmez). Bir dönüş türü belirtilmezse, dönüş türü ifadeden çıkarılır. Uzantı tabanlı uygulamalar NatVis dosyasında bir dönüş türü belirtmelidir.
Diğer iç işlevlere özyinelemeli olmayan çağrılara izin verilir. Özyineleme işlemine izin verilmiyor.
İşlevin yan etkileri varsa bildirimde
SideEffect="true"belirtmeniz gerekir. İfade tabanlı bir uygulamada, işlevin yan etkileri olduğu belirtilmeden, ifadede yan etkiler bulunması yasadışıdır. Yan etkilere sahip işlevi bildirmeden yan etkilere sahip olmak için uzantı tabanlı bir uygulamayı çağırmak tanımsız bir davranıştır ve bundan kaçınılmalıdır.Varargs iç işlevlerine izin verilir. Varargs işlevini bildirmek için bildirimde
Varargs="true"belirtin. İfade tabanlı bir uygulamanın birvarargişlevi bildirmesi yasal olsa da, şu anda yalnızca uzantı tabanlı uygulamalar değişken bağımsız değişkenlerine erişmek için bir yönteme sahiptir. Uzantı tabanlı bir uygulamayla,Execute()işlevi yalnızca bildirilen bağımsız değişkenleri değil, aslında geçirilen tüm bağımsız değişkenleri alır.Argüman olarak sınıf/yapı/birleşim türü kullanan dahili fonksiyonlar desteklenmez. Sınıf/yapı/birleşim türü döndürme işlemi Tamam'dır. Bir sınıf, yapı veya birleşim türüne yönelik işaretçi veya referans, bağımsız değişken türü olarak uygundur.
İç işlevlere yapılan çağrılar için simgeyi özelleştirin.
Varsayılan olarak, bir iç işlevi çağırdığınızda, ifadeye işlev çağrılarıyla ilişkilendirilmiş İzle penceresinde pembe elmas simgesi verilir. Aşağıdaki değerlerden birini kullanarak Category özniteliğini belirterek bu davranışı geçersiz kılabilirsiniz:
- Yöntem. Genellikle yöntem çağrılarıyla (varsayılan) kullanılan pembe elmas simgesini kullanın.
- Mülk. Genellikle özelliklerle birlikte kullanılan siyah anahtar simgesini kullanın.
- Veri. Mavi elmas simgesini, genellikle verilerle birlikte kullanılan, kullanın.
İç işlevleri <Item> öğesiyle birleştirerek, öğe ifadelerinin anahtar özelliği simgesine sahip olduğu bir NatVis dosyası yazılabilir:
<Type Name="MyClass">
<Intrinsic Name="GetValue" ReturnType="int" Expression="m_value" Category="Property" />
<Expand>
<Item Name="Value">this->GetValue()</Item>
</Expand>
</Type>
Not
İkon seçiminin <Item> düzeyinde değil, işlev düzeyinde yapılması, tam adın değerlendirildiğinde simge özelleştirmenin kaybolmaması sorununu önler. Tam adı bir işlev çağrısı içerdiğinden, <Item> ile aynı simge özelleştirmesine sahiptir.