Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I det här avsnittet beskrivs hur du använder C++-objekt för felsökningsdatamodell och hur de kan utöka funktionerna i felsökningsprogrammet.
Core Debugger Object Model
En av de mest grundläggande men kraftfulla sakerna med datamodellen är att den standardiserar definitionen av vad ett objekt är och hur man interagerar med ett objekt. Det IModelObject--gränssnittet kapslar in begreppet objekt – oavsett om objektet är ett heltal, ett flyttalvärde, en sträng, någon komplex typ i måladressutrymmet för felsökaren eller något felsökningskoncept som begreppet process eller en modul.
Det finns flera olika saker som kan hållas i (eller boxas in i) en IModelObject:
Intrinsic Values – En IModelObject- kan vara en container för ett antal grundläggande typer: 8, 16, 32 eller 64 bitars signerade eller osignerade heltal, booleska, strängar, fel eller begreppet tomt.
interna objekt – En IModelObject- kan representera en komplex typ (som definieras av felsökarens typsystem) inom adressutrymmet för vad felsökningsprogrammet riktar sig till
syntetiska objekt – En IModelObject- kan vara ett dynamiskt objekt – en ordlista om du vill: en samling nyckel/värde/metadatatupplar och en uppsättning begrepp som definierar beteenden som inte bara representeras av nyckel-/värdepar.
Egenskaper – en IModelObject- kan representera en egenskap: något vars värde kan hämtas eller ändras med ett metodanrop. En egenskap i en IModelObject- är i själva verket ett IModelPropertyAccessor- gränssnitt som är inramat i ett IModelObject-
Methods – En IModelObject- kan representera en metod: något du kan anropa med en uppsättning argument och få ett returvärde. En metod i ett IModelObject- är i själva verket ett IModelMethod- gränssnitt som är inramat i ett IModelObject-
Utökningsbarhet i objektmodellen
En IModelObject- är inte ett isolerat objekt. Förutom att representera en av de typer av objekt som visas ovan, har varje objekt begreppet en kedja med överordnade datamodeller. Den här kedjan fungerar ungefär som en JavaScript-prototypkedja. I stället för en linjär kedja av prototyper som JavaScript har definierar varje datamodellobjekt en linjär kedja av överordnade modeller. Var och en av dessa överordnade modeller har i sin tur en annan linjär kedja av sin egen uppsättning föräldrar. I grund och botten är varje objekt en aggregering av funktionerna (egenskaper osv.) för både sig själv och varje objekt i det här trädet. När en specifik egenskap efterfrågas skickas frågan i linjär ordning till varje överordnad i tur och ordning om det objekt som den efterfrågas på inte stöder den egenskapen. Detta skapar ett beteende där sökningen efter en egenskap löses av en djupsökning av samlingsträdet.
Utökningsbarheten i den här objektmodellen är mycket enkel med tanke på den här uppfattningen att varje objekt är en samling av sig själv och trädet för överordnade modeller. Ett tillägg kan komma in och lägga till sig själv i listan över överordnade modeller för ett annat objekt. Om du gör det här utökas objektet. På så sätt är det möjligt att lägga till funktioner på allt: en viss instans av ett objekt eller värde, en intern typ, felsökningsprogrammets koncept för vad en process eller tråd är, eller till och med begreppet "alla iterbara objekt".
Kontext, kontext och kontext: den här pekaren, adressutrymmet och privata implementeringsdata
Det finns tre begrepp om kontext som är nödvändiga för att förstå inom ramen för objektmodellen.
Kontext: den här pekaren
Eftersom en viss egenskap eller metod kan implementeras på vilken nivå som helst i datamodellträdet är det nödvändigt att implementeringen av metoden eller egenskapen kan komma åt det ursprungliga objektet (vad du kan kalla den här pekaren i C++ eller det här objektet i JavaScript. Instansobjektet skickas till en mängd olika metoder som det första argumentet som kallas kontext i metoderna som beskrivs.
Kontext: Adressutrymmet
Det är viktigt att observera att till skillnad från tidigare tilläggsmodeller där kontext (målet, processen, tråden du tittar på) är ett gränssnittskoncept med alla API:er i förhållande till det aktuella användargränssnittets tillstånd, tar datamodellgränssnitt vanligtvis den här kontexten antingen explicit eller implicit som ett IDebugHostContext--gränssnitt. Varje IModelObject- i datamodellen innehåller den här typen av kontextinformation och kan sprida kontexten till objekt som den returnerar. Det innebär att när du läser ett inbyggt värde eller ett nyckelvärde från en IModelObject, läses det ut från målet och processen där objektet ursprungligen hämtades från.
Det finns ett explicit konstant värde, USE_CURRENT_HOST_CONTEXT, som kan skickas till metoder som tar ett IDebugHostContext argument. Det här värdet anger att kontexten verkligen ska vara det aktuella användargränssnittstillståndet för felsökningsprogrammet. Denna uppfattning måste dock vara explicit.
Kontext: Implementering av privata data
Kom ihåg att varje objekt i datamodellen faktiskt är en aggregering av objektinstansen och trädet för överordnade modeller som är anslutna. Var och en av dessa överordnade modeller (som kan länkas i kedjorna för många olika objekt) kan associera privata implementeringsdata med valfritt instansobjekt. Varje IModelObject- som skapas konceptuellt har en hash-tabell som mappar från en viss överordnad modell till privata instansdata som definierats av ett IUnknown-gränssnitt. På så sätt kan en överordnad modell cachelagras information om varje instans eller ha andra godtyckliga data associerade.
Den här typen av kontext nås via metoderna GetContextForDataModel och SetContextForDataModel på IModelObject.
Kärnfelsökarobjektgränssnittet: IModelObject
Gränssnittet IModelObject definieras på följande sätt:
DECLARE_INTERFACE_(IModelObject, IUnknown)
{
STDMETHOD(QueryInterface)(_In_ REFIID iid, _COM_Outptr_ PVOID* iface);
STDMETHOD_(ULONG, AddRef)();
STDMETHOD_(ULONG, Release)() PURE;
STDMETHOD(GetContext)(_COM_Outptr_result_maybenull_ IDebugHostContext** context) PURE;
STDMETHOD(GetKind)(_Out_ ModelObjectKind *kind) PURE;
STDMETHOD(GetIntrinsicValue)(_Out_ VARIANT* intrinsicData);
STDMETHOD(GetIntrinsicValueAs)(_In_ VARTYPE vt, _Out_ VARIANT* intrinsicData) PURE;
STDMETHOD(GetKeyValue)(_In_ PCWSTR key, _COM_Errorptr_opt_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
STDMETHOD(SetKeyValue)(_In_ PCWSTR key, _In_opt_ IModelObject* object) PURE;
STDMETHOD(EnumerateKeyValues)(_COM_Outptr_ IKeyEnumerator** enumerator) PURE;
STDMETHOD(GetRawValue)(_In_ SymbolKind kind, _In_ PCWSTR name, _In_ ULONG searchFlags, _COM_Errorptr_ IModelObject** object) PURE;
STDMETHOD(EnumerateRawValues)(_In_ SymbolKind kind, _In_ ULONG searchFlags, _COM_Outptr_ IRawEnumerator** enumerator) PURE;
STDMETHOD(Dereference)(_COM_Errorptr_ IModelObject** object) PURE;
STDMETHOD(TryCastToRuntimeType)(_COM_Errorptr_ IModelObject** runtimeTypedObject) PURE;
STDMETHOD(GetConcept)(_In_ REFIID conceptId, _COM_Outptr_ IUnknown** conceptInterface, _COM_Outptr_opt_result_maybenull_ IKeyStore** conceptMetadata) PURE;
STDMETHOD(GetLocation)(_Out_ Location* location) PURE;
STDMETHOD(GetTypeInfo)(_Out_ IDebugHostType** type) PURE;
STDMETHOD(GetTargetInfo)(_Out_ Location* location, _Out_ IDebugHostType** type) PURE;
STDMETHOD(GetNumberOfParentModels)(_Out_ ULONG64* numModels) PURE;
STDMETHOD(GetParentModel)(_In_ ULONG64 i, _COM_Outptr_ IModelObject **model, _COM_Outptr_result_maybenull_ IModelObject **contextObject) PURE;
STDMETHOD(AddParentModel)(_In_ IModelObject* model, _In_opt_ IModelObject* contextObject, _In_ bool override) PURE;
STDMETHOD(RemoveParentModel)(_In_ IModelObject* model) PURE;
STDMETHOD(GetKey)(_In_ PCWSTR key, _COM_Errorptr_opt_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
STDMETHOD(GetKeyReference)(_In_ PCWSTR key, _COM_Errorptr_opt_ IModelObject** objectReference, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
STDMETHOD(SetKey)(_In_ PCWSTR key, _In_opt_ IModelObject* object, _In_opt_ IKeyStore* metadata) PURE;
STDMETHOD(ClearKeys)() PURE;
STDMETHOD(EnumerateKeys)(_COM_Outptr_ IKeyEnumerator** enumerator) PURE;
STDMETHOD(EnumerateKeyReferences)(_COM_Outptr_ IKeyEnumerator** enumerator) PURE;
STDMETHOD(SetConcept)(_In_ REFIID conceptId, _In_ IUnknown* conceptInterface, _In_opt_ IKeyStore* conceptMetadata) PURE;
STDMETHOD(ClearConcepts)() PURE;
STDMETHOD(GetRawReference)(_In_ SymbolKind kind, _In_ PCWSTR name, _In_ ULONG searchFlags, _COM_Errorptr_ IModelObject** object) PURE;
STDMETHOD(EnumerateRawReferences)(_In_ SymbolKind kind, _In_ ULONG searchFlags, _COM_Outptr_ IRawEnumerator** enumerator) PURE;
STDMETHOD(SetContextForDataModel)(_In_ IModelObject* dataModelObject, _In_ IUnknown* context) PURE;
STDMETHOD(GetContextForDataModel)(_In_ IModelObject* dataModelObject, _Out_ IUnknown** context) PURE;
STDMETHOD(Compare)(_In_ IModelObject* other, _COM_Outptr_opt_result_maybenull_ IModelObject **ppResult) PURE;
STDMETHOD(IsEqualTo)(_In_ IModelObject* other, _Out_ bool* equal) PURE;
}
Grundläggande metoder
Följande är allmänna metoder som gäller för alla typer av objekt som representeras av en IModelObject.
STDMETHOD(GetKind)(_Out_ ModelObjectKind *kind) PURE;
STDMETHOD(GetContext)(_COM_Outptr_result_maybenull_ IDebugHostContext** context) PURE;
STDMETHOD(GetIntrinsicValue)(_Out_ VARIANT* intrinsicData);
STDMETHOD(GetIntrinsicValueAs)(_In_ VARTYPE vt, _Out_ VARIANT* intrinsicData) PURE;
STDMETHOD(Compare)(_In_ IModelObject* other, _COM_Outptr_opt_result_maybenull_ IModelObject **ppResult) PURE;
STDMETHOD(IsEqualTo)(_In_ IModelObject* other, _Out_ bool* equal) PURE;
STDMETHOD(Dereference)(_COM_Errorptr_ IModelObject** object) PURE;
Metoden GetKind returnerar vilken typ av objekt som boxas i IModelObject.
Metoden GetContext returnerar värdkontexten som är associerad med objektet.
Metoden GetIntrinsicValue returnerar det som boxas i en IModelObject. Den här metoden får endast anropas lagligt på IModelObject-gränssnitt som representerar ett inramat inbyggt eller ett visst gränssnitt som är rutat. Det kan inte anropas på inbyggda objekt, inga värdeobjekt, syntetiska objekt och referensobjekt. Metoden GetIntrinsicValueAs fungerar ungefär som metoden GetIntrinsicValue, förutom att den konverterar värdet till den angivna varianttypen. Om konverteringen inte kan utföras returnerar metoden ett fel.
Metoden IsEqualTo jämför två modellobjekt och returnerar om de är lika med i värde. För objekt som har en ordning motsvarar den här metoden som returnerar true metoden Jämför-metoden som returnerar 0. För objekt som inte har någon ordning men är ekvabel misslyckas metoden Compare, men det kommer inte att göra det. Innebörden av en värdebaserad jämförelse definieras av typen av objekt. För närvarande definieras detta endast för inbyggda typer och felobjekt. Det finns inget aktuellt datamodellkoncept för liknbarhet.
Dereference-metoden avrefererar ett objekt. Den här metoden kan användas för att avreferera en datamodellbaserad referens (ObjectTargetObjectReference, ObjectKeyReference) eller en referens på det interna språket (en pekare eller en språkreferens). Observera att den här metoden tar bort en enda nivå av referenssemantik på objektet. Det är helt möjligt att till exempel ha en datamodellreferens till en språkreferens. I sådana fall skulle anrop av dereference-metoden första gången ta bort datamodellreferensen och lämna språkreferensen. Om du anropar dereference för det resulterande objektet skulle språkreferensen därefter ta bort och returnera det interna värdet under den referensen.
metoder för nyckelmanipulering
Alla syntetiska objekt som är en ordlista med nyckel-, värde- och metadatatupplar har en serie metoder för att manipulera dessa nycklar, värden och metadata som är associerade med dem.
De värdebaserade formulären för API:erna är:
STDMETHOD(GetKeyValue)(_In_ PCWSTR key, _COM_Errorptr_opt_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
STDMETHOD(SetKeyValue)(_In_ PCWSTR key, _In_opt_ IModelObject* object) PURE;
STDMETHOD(EnumerateKeyValues)(_COM_Outptr_ IKeyEnumerator** enumerator) PURE;
The key based forms of the APIs (including those used for key creation) are:
STDMETHOD(GetKey)(_In_ PCWSTR key, _COM_Errorptr_opt_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
STDMETHOD(SetKey)(_In_ PCWSTR key, _In_opt_ IModelObject* object, _In_opt_ IKeyStore* metadata) PURE;
STDMETHOD(EnumerateKeys)(_COM_Outptr_ IKeyEnumerator** enumerator) PURE;
STDMETHOD(ClearKeys)() PURE;
Referensbaserade formulär för API:erna är:
STDMETHOD(GetKeyReference)(_In_ PCWSTR key, _COM_Errorptr_opt_ IModelObject** objectReference, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
STDMETHOD(EnumerateKeyReferences)(_COM_Outptr_ IKeyEnumerator** enumerator) PURE;
Metoden GetKeyValue är den första metoden som en klient vänder sig till för att hämta värdet för (och de metadata som är associerade med) en viss nyckel efter namn. Om nyckeln är en egenskapsåtkomst – det vill säga värdet som en IModelObject som är en boxad IModelPropertyAccessor anropar metoden GetKeyValue automatiskt egenskapsåtkomstgivarens GetValue-metod för att hämta det faktiska värdet.
Metoden SetKeyValue är den första metoden som en klient vänder sig till för att ange värdet för en nyckel. Den här metoden kan inte användas för att skapa en ny nyckel för ett objekt. Den anger bara värdet för en befintlig nyckel. Observera att många nycklar är skrivskyddade (t.ex. implementeras de av en egenskapsåtkomst som returnerar E_NOT_IMPL från setvalue-metoden). Den här metoden misslyckas när den anropas på en skrivskyddad nyckel.
Metoden EnumerateKeyValues är den första metoden som en klient vänder sig till för att räkna upp alla nycklar på ett objekt (detta inkluderar alla nycklar som implementeras var som helst i trädet för överordnade modeller). Observera att EnumerateKeyValues räknar upp alla nycklar som definieras av dubblettnamn i objektträdet. men - metoder som GetKeyValue och SetKeyValue ändrar bara den första instansen av en nyckel med det förnamn som identifieras av djup-först-traverseringen.
Metoden GetKey hämtar värdet för (och metadata som är associerade med) en viss nyckel efter namn. De flesta klienter bör använda metoden GetKeyValue i stället. Om nyckeln är en egenskapsåtkomst returnerar anropet av den här metoden egenskapsåtkomsten (ett IModelPropertyAccessor-gränssnitt) i en IModelObject. Till skillnad från GetKeyValue löser den här metoden inte automatiskt det underliggande värdet för nyckeln genom att anropa metoden GetValue. Det ansvaret är uppringarens.
Metoden SetKey är den metod som en klient vänder sig till för att skapa en nyckel för ett objekt (och eventuellt associera metadata med den skapade nyckeln). Om ett angivet objekt redan har en nyckel med det angivna namnet inträffar ett av två beteenden. Om nyckeln finns på den instans som anges av detta ersätts värdet för den nyckeln som om den ursprungliga nyckeln inte fanns. Om nyckeln å andra sidan finns i kedjan med överordnade datamodeller för den instans som anges av den här, skapas en ny nyckel med det angivna namnet på den instans som anges av detta. Detta skulle i själva verket leda till att objektet har två nycklar med samma namn (ungefär som en härledd klass som skuggar en medlem med samma namn som en basklass).
Metoden EnumerateKeys fungerar ungefär som metoden EnumerateKeyValues, förutom att den inte automatiskt löser egenskapsåtkomster för objektet. Det innebär att om värdet för en nyckel är en egenskapsåtkomst returnerar metoden EnumerateKeys egenskapsåtkomsten (en IModelPropertyAccessorInterface) i en IModelObject i stället för att automatiskt anropa Metoden GetValue. Detta liknar skillnaden mellan GetKey och GetKeyValue.
Metoden ClearKeys tar bort alla nycklar och deras associerade värden och metadata från instansen av objektet som anges av detta. Den här metoden påverkar inte överordnade modeller som är kopplade till den specifika objektinstansen.
Metoden GetKeyReference söker efter en nyckel i det angivna namnet på objektet (eller dess överordnade modellkedja) och returnerar en referens till den nyckel som anges av ett IModelKeyReference-gränssnitt som är inrutat i en IModelObject. Referensen kan sedan användas för att hämta eller ange värdet för nyckeln.
Metoden EnumerateKeyReferences fungerar ungefär som metoden EnumerateKeyValues, förutom att den returnerar referenser till de nycklar som den räknar upp (som anges av ett IModelKeyReference-gränssnitt som boxas till en IModelObject) i stället för värdet för nyckeln. Sådana referenser kan användas för att hämta eller ange det underliggande värdet för nycklarna.
Concept Manipulation Methods
Förutom att ett modellobjekt är en ordlista med nyckel/värde/metadatatupplar är det också en container med begrepp. Ett begrepp är något abstrakt som kan utföras på eller av ett objekt. Begrepp är i huvudsak ett dynamiskt lager av gränssnitt som ett objekt stöder. Ett antal begrepp definieras av datamodellen idag:
| Konceptgränssnitt | Beskrivning |
|---|---|
| IDataModelConcept | Konceptet är en överordnad modell. Om den här modellen automatiskt kopplas till en intern typ via en registrerad typsignatur anropas metoden InitializeObject automatiskt varje gång ett nytt objekt av den här typen instansieras. |
| IStringDisplayableConcept | Objektet kan konverteras till en sträng i visningssyfte. |
| IIterableConcept | Objektet är en container och kan itereras. |
| IIndexableConcept | Objektet är en container och kan indexeras (nås via slumpmässig åtkomst) i en eller flera dimensioner. |
| IPreferredRuntimeTypeConcept | Objektet förstår mer om typer som härleds från det än det underliggande typsystemet kan tillhandahålla och vill hantera sina egna konverteringar från statisk till körningstyp. |
| IDynamicKeyProviderConcept | Objektet är en dynamisk provider av nycklar och vill ta över alla viktiga frågor från kärndatamodellen. Det här gränssnittet används vanligtvis som en brygga till dynamiska språk, till exempel JavaScript. |
| IDynamicConceptProviderConcept | Objektet är en dynamisk leverantör av begrepp och vill ta över alla konceptfrågor från kärndatamodellen. Det här gränssnittet används vanligtvis som en brygga till dynamiska språk, till exempel JavaScript. |
Följande metoder på IModelObject används för att ändra de begrepp som ett objekt stöder.
STDMETHOD(GetConcept)(_In_ REFIID conceptId, _COM_Outptr_ IUnknown** conceptInterface, _COM_Outptr_opt_result_maybenull_ IKeyStore** conceptMetadata) PURE;
STDMETHOD(SetConcept)(_In_ REFIID conceptId, _In_ IUnknown* conceptInterface, _In_opt_ IKeyStore* conceptMetadata) PURE;
STDMETHOD(ClearConcepts)() PURE;
Metoden GetConcept söker efter ett koncept i objektet (eller dess överordnade modellkedja) och returnerar en gränssnittspekare till konceptgränssnittet. Beteendet och metoderna i ett konceptgränssnitt är specifika för varje koncept. Det är dock viktigt att notera att många av konceptgränssnitten kräver att anroparen uttryckligen skickar kontextobjektet (eller vad man traditionellt kan kalla den här pekaren). Det är viktigt att se till att rätt kontextobjekt skickas till varje konceptgränssnitt.
Metoden SetConcept placerar ett angivet begrepp på den objektinstans som anges av den här pekaren. Om en överordnad modell som är kopplad till den objektinstans som anges av detta också stöder konceptet åsidosätter implementeringen i instansen den i den överordnade modellen.
Metoden ClearConcepts tar bort alla begrepp från instansen av objektet som anges av detta.
interna objektmetoder
Även om många modellobjekt refererar till inbyggda (t.ex. heltal, strängar) eller syntetiska konstruktioner (en ordlista med nyckel/värde/metadatatupplar och begrepp), kan ett modellobjekt också referera till en inbyggd konstruktion (t.ex. en användardefinierad typ i adressutrymmet för felsökningsmålet). IModelObject-gränssnittet har en serie metoder som har åtkomst till information om sådana inbyggda objekt. Dessa metoder är:
STDMETHOD(GetRawValue)(_In_ SymbolKind kind, _In_ PCWSTR name, _In_ ULONG searchFlags, _COM_Errorptr_ IModelObject** object) PURE;
STDMETHOD(EnumerateRawValues)(_In_ SymbolKind kind, _In_ ULONG searchFlags, _COM_Outptr_ IRawEnumerator** enumerator) PURE;
STDMETHOD(TryCastToRuntimeType)(_COM_Errorptr_ IModelObject** runtimeTypedObject) PURE;
STDMETHOD(GetLocation)(_Out_ Location* location) PURE;
STDMETHOD(GetTypeInfo)(_Out_ IDebugHostType** type) PURE;
STDMETHOD(GetTargetInfo)(_Out_ Location* location, _Out_ IDebugHostType** type) PURE;
STDMETHOD(GetRawReference)(_In_ SymbolKind kind, _In_ PCWSTR name, _In_ ULONG searchFlags, _COM_Errorptr_ IModelObject** object) PURE;
STDMETHOD(EnumerateRawReferences)(_In_ SymbolKind kind, _In_ ULONG searchFlags, _COM_Outptr_ IRawEnumerator** enumerator) PURE;
Metoden GetRawValue hittar en inbyggd konstruktion i det angivna objektet. En sådan konstruktion kan vara ett fält, en basklass, ett fält i en basklass, en medlemsfunktion osv.
Metoden EnumerateRawValues räknar upp alla inbyggda underordnade objekt (t.ex. fält, basklasser osv.) för det angivna objektet.
Metoden TryCastToRuntimeType ber felsökningsvärden att utföra en analys och fastställa den faktiska körningstypen (t.ex. den mest härledda klassen) för det angivna objektet. Den exakta analys som används är specifik för felsökningsvärden och kan innehålla INFORMATION om RTTI (C++-körningstid), undersökning av objektets V-tabellstruktur (virtuell funktionstabell) eller något annat sätt som värden kan använda för att på ett tillförlitligt sätt fastställa dynamisk/körningstyp från den statiska typen. Om det inte går att konvertera till en körningstyp innebär det inte att det här metodanropet misslyckas. I sådana fall returnerar metoden det angivna objektet (den här pekaren) i utdataargumentet.
Metoden GetLocation returnerar platsen för det interna objektet. Även om en sådan plats vanligtvis är en virtuell adress inom adressutrymmet för felsökningsmålet är det inte nödvändigtvis så. Den plats som returneras av den här metoden är en abstrakt plats som kan vara en virtuell adress, som kan tyda på placering i ett register eller underregister, eller kan tyda på något annat godtyckligt adressutrymme som definieras av felsökningsvärden. Om fältet HostDefined för det resulterande platsobjektet är 0 anger det att platsen faktiskt är en virtuell adress. En sådan virtuell adress kan hämtas genom att undersöka förskjutningsfältet på den resulterande platsen. Alla värden som inte är noll för fältet HostDefined anger ett alternativt adressutrymme där fältet Offset är förskjutningen inom adressutrymmet. Den exakta innebörden av värden som inte är noll Fördefinierade värden här är privata för felsökningsvärden.
Metoden GetTypeInfo returnerar den interna typen av det angivna objektet. Om objektet inte har intern typinformation associerad med det (t.ex. att det är en inbyggd osv.) kommer anropet fortfarande att lyckas men returnerar null.
Metoden GetTargetInfo är i själva verket en kombination av metoderna GetLocation och GetTypeInfo som returnerar både den abstrakta platsen och den inbyggda typen av det angivna objektet.
Metoden GetRawReference hittar en inbyggd konstruktion i det angivna objektet och returnerar en referens till den. En sådan konstruktion kan vara ett fält, en basklass, ett fält i en basklass, en medlemsfunktion osv. Det är viktigt att skilja referensen som returneras här (ett objekt av typen ObjectTargetObjectReference) från en språkreferens (t.ex. en C++ & eller && formatreferens).
Metoden EnumerateRawReferences räknar upp referenser till alla inbyggda underordnade (t.ex. fält, basklasser osv.) för det angivna objektet.
Utökningsmetoder
Som tidigare beskrivits fungerar ett modellobjekt ungefär som ett JavaScript-objekt och dess prototypkedja. Förutom den instans som representeras av ett visst IModelObject-gränssnitt kan det finnas ett godtyckligt antal överordnade modeller som är kopplade till objektet (som var och en i sin tur kan ha ett godtyckligt antal överordnade modeller kopplade till sig). Det här är det primära sättet för utökningsbarhet i datamodellen. Om en viss egenskap eller ett visst begrepp inte kan hittas inom en viss instans utförs en djupsökning av objektträdet (definierat av överordnade modeller) som är rotat på instansen.
Följande metoder manipulerar kedjan med överordnade modeller som är associerade med en viss IModelObject-instans:
STDMETHOD(GetNumberOfParentModels)(_Out_ ULONG64* numModels) PURE;
STDMETHOD(GetParentModel)(_In_ ULONG64 i, _COM_Outptr_ IModelObject **model, _COM_Outptr_result_maybenull_ IModelObject **contextObject) PURE;
STDMETHOD(AddParentModel)(_In_ IModelObject* model, _In_opt_ IModelObject* contextObject, _In_ bool override) PURE;
STDMETHOD(RemoveParentModel)(_In_ IModelObject* model) PURE;
STDMETHOD(SetContextForDataModel)(_In_ IModelObject* dataModelObject, _In_ IUnknown* context) PURE;
STDMETHOD(GetContextForDataModel)(_In_ IModelObject* dataModelObject, _Out_ IUnknown** context) PURE;
Metoden GetNumberOfParentModels returnerar antalet överordnade modeller som är kopplade till den angivna objektinstansen. Överordnade modeller söks efter egenskaper djup först i den linjära ordningen i den överordnade modellkedjan.
Metoden GetParentModel returnerar den överordnade modellen i-th i den överordnade modellkedjan för det angivna objektet. Överordnade modeller söks efter en egenskap eller ett begrepp i den linjära ordning som de läggs till eller räknas upp. Den överordnade modellen med index i på noll söks (hierarkiskt) före den överordnade modellen med index i + 1.
Metoden AddParentModel lägger till en ny överordnad modell i det angivna objektet. En sådan modell kan läggas till i slutet av sökkedjan (åsidosättningsargumentet anges som falskt) eller längst fram i sökkedjan (åsidosättningsargumentet anges som sant). Dessutom kan varje överordnad modell eventuellt justera kontexten (den semantiska pekaren) för alla egenskaper eller begrepp på den angivna överordnade (eller någon i dess överordnade hierarki). Kontextjustering används sällan men tillåter vissa kraftfulla begrepp som inbäddning av objekt, konstruera namnområden osv.
RemoveParentModel tar bort en angiven överordnad modell från den överordnade sökkedjan för det angivna objektet.
Metoden SetContextForDataModel används av implementeringen av en datamodell för att placera implementeringsdata på instansobjekt. Konceptuellt innehåller varje IModelObject (anropa den här instansen för enkelhetens skull) en hash-tabell med tillstånd. Hash-tabellen indexeras av en annan IModelObject (anropa datamodellen för enkelhetens skull) som finns i instansens överordnade modellhierarki. Värdet i den här hashen är en uppsättning referensantal tillståndsinformation som representeras av en IUnknown-instans. När datamodellen anger det här tillståndet på instansen kan den lagra godtyckliga implementeringsdata som kan hämtas under saker som egenskapsmottagare.
Metoden GetContextForDataModel används för att hämta kontextinformation som konfigurerades med ett tidigare anrop till SetContextForDataModel. Detta hämtar tillståndsinformation som har angetts för ett instansobjekt av en datamodell längre upp i instansobjektets överordnade modellhierarki. Mer information om den här kontexten/tillståndet och dess betydelse finns i dokumentationen för SetContextForDataModel.
Data Model Core-objekttyper för felsökning
Ett objekt i datamodellen liknar begreppet Objekt i .NET. Det är den generiska container i vilken konstruktionen som datamodellen förstår kan boxas. Förutom inbyggda objekt och syntetiska (dynamiska) objekt finns det en serie kärnobjekttyper som kan placeras (eller boxas) i containern för en IModelObject. Containern där de flesta av dessa värden placeras är en COM/OLE-standardvariant med ett antal ytterligare begränsningar för vad varianten kan innehålla. De mest grundläggande typerna av dessa är:
- 8-bitars osignerade och signerade värden (VT_UI1, VT_I1)
- 16-bitars osignerade och signerade värden (VT_UI2, VT_UI2)
- 32-bitars osignerade och signerade värden (VT_UI4, VT_I4)
- 64-bitars osignerade och signerade värden (VT_UI8, VT_I8)
- Flyttalsvärden med enkel och dubbel precision (VT_R4, VT_R8)
- Strängar (VT_BSTR)
- Booleska (VT_BOOL)
Utöver dessa grundläggande typer placeras ett antal kärndatamodellobjekt i IModelObject som definierats av VT_UNKNOWN där den lagrade IUnknown garanterat implementerar ett specifikt gränssnitt. Följande typer är:
- Egenskapsåtkomster (IModelPropertyAccessor)
- Metodobjekt (IModelMethod)
- Nyckelreferensobjekt (IModelKeyReference eller IModelKeyReference2)
- Kontextobjekt (IDebugModelHostContext)
-egenskapsåtkomster: IModelPropertyAccessor
En egenskapsåtkomst i datamodellen är en implementering av gränssnittet IModelPropertyAccessor som boxas till en IModelObject. Modellobjektet returnerar en typ av ObjectPropertyAccessor när det efterfrågas och det inbyggda värdet är en VT_UNKNOWN som garanterat kan frågas efter IModelPropertyAccessor. I processen är det garanterat statiskt gjutbart för IModelPropertyAccessor.
En egenskapsåtkomst är ett indirekt sätt att få ett metodanrop för att hämta och ange ett nyckelvärde i datamodellen. Om en viss nyckels värde är en egenskapsåtkomst, kommer metoderna GetKeyValue och SetKeyValue automatiskt att märka detta och anropa egenskapsåtkomstens underliggande GetValue- eller SetValue-metoder efter behov.
Gränssnittet IModelPropertyAccessor definieras på följande sätt:
DECLARE_INTERFACE_(IModelPropertyAccessor, IUnknown)
{
STDMETHOD(GetValue)(_In_ PCWSTR key, _In_opt_ IModelObject* contextObject, _COM_Outptr_ IModelObject** value) PURE;
STDMETHOD(SetValue)(_In_ PCWSTR key, _In_opt_ IModelObject* contextObject, _In_ IModelObject* value) PURE;
}
Metoden GetValue är getter för egenskapsåtkomstorn. Det anropas när en klient vill hämta det underliggande värdet för egenskapen. Observera att alla anropare som direkt hämtar en egenskapsåtkomst är ansvarig för att skicka nyckelnamnet och det korrekta instansobjektet (den här pekaren) till egenskapsåtkomstgivarens GetValue-metod.
Metoden SetValue är setter för egenskapsåtkomstorn. Det anropas när en klient vill tilldela ett värde till den underliggande egenskapen. Många egenskaper är skrivskyddade. I sådana fall returnerar anropet av metoden SetValue E_NOTIMPL. Observera att alla anropare som direkt hämtar en egenskapsåtkomst är ansvarig för att skicka nyckelnamnet och det korrekta instansobjektet (den här pekaren) till egenskapsåtkomstgivarens SetValue-metod.
metoder: IModelMethod
En metod i datamodellen är en implementering av IModelMethod-gränssnittet som boxas in i en IModelObject. Modellobjektet returnerar en typ av ObjectMethod när det efterfrågas och det inbyggda värdet är en VT_UNKNOWN som garanterat kan köras frågor mot IModelMethod. I processen är det garanterat att vara statiskt gjutbart för IModelMethod. Alla metoder i datamodellen är dynamiska till sin natur. De tar som indata en uppsättning med 0 eller fler argument och returnerar ett enda utdatavärde. Det finns ingen överbelastningsmatchning och inga metadata om parameternamn, typer eller förväntningar.
Gränssnittet IModelMethod definieras på följande sätt:
DECLARE_INTERFACE_(IModelMethod, IUnknown)
{
STDMETHOD(Call)(_In_opt_ IModelObject *pContextObject, _In_ ULONG64 argCount, _In_reads_(argCount) IModelObject **ppArguments, _COM_Errorptr_ IModelObject **ppResult, _COM_Outptr_opt_result_maybenull_ IKeyStore **ppMetadata) PURE;
}
Anropsmetoden är det sätt på vilket alla metoder som definierats i datamodellen anropas. Anroparen ansvarar för att skicka ett korrekt instansobjekt (den här pekaren) och en godtycklig uppsättning argument. Resultatet av metoden och eventuella valfria metadata som är associerade med det resultatet returneras. Metoder som inte returnerar ett värde logiskt måste fortfarande returnera en giltig IModelObject. I så fall är IModelObject ett rutat inget värde. Om en metod misslyckas kan den returnera valfri utökad felinformation i indataargumentet (även om den returnerade HRESULT:en är ett fel). Det är absolut nödvändigt att uppringare söker efter detta.
nyckelreferenser: IModelKeyReference eller IModelKeyReference2
En nyckelreferens är i huvudsak ett handtag till en nyckel för ett visst objekt. En klient kan hämta sådana handtag via metoder som GetKeyReference och använda handtaget senare för att hämta eller ange värdet för nyckeln utan att nödvändigtvis hålla fast vid det ursprungliga objektet. Den här typen av objekt är en implementering av gränssnittet IModelKeyReference eller IModelKeyReference2 som är inramat i en IModelObject. Modellobjektet returnerar en typ av ObjectKeyReference när det efterfrågas och det inbyggda värdet är en VT_UNKNOWN som garanterat kan köras frågor för IModelKeyReference. Processen är garanterad att vara statiskt kastbar för IModelKeyReference.
Nyckelreferensgränssnittet definieras på följande sätt:
DECLARE_INTERFACE_(IModelKeyReference2, IModelKeyReference)
{
STDMETHOD(GetKeyName)(_Out_ BSTR* keyName) PURE;
STDMETHOD(GetOriginalObject)(_COM_Outptr_ IModelObject** originalObject) PURE;
STDMETHOD(GetContextObject)(_COM_Outptr_ IModelObject** containingObject) PURE;
STDMETHOD(GetKey)(_COM_Errorptr_opt_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
STDMETHOD(GetKeyValue)(_COM_Errorptr_opt_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
STDMETHOD(SetKey)(_In_opt_ IModelObject* object, _In_opt_ IKeyStore* metadata) PURE;
STDMETHOD(SetKeyValue)(_In_ IModelObject* object) PURE;
STDMETHOD(OverrideContextObject)(_In_ IModelObject* newContextObject) PURE;
}
Metoden GetKeyName returnerar namnet på nyckeln som nyckelreferensen är en referens till. Den returnerade strängen är en vanlig BSTR och måste friges via ett anrop till SysFreeString.
Metoden GetOriginalObject returnerar instansobjektet som nyckelreferensen skapades från. Observera att själva nyckeln kan finnas på en överordnad modell för instansobjektet.
Metoden GetContextObject returnerar kontexten (den här pekaren) som skickas till en egenskapsåtkomstleverantörs GetValue- eller SetValue-metod om nyckeln i fråga refererar till en egenskapsåtkomst. Kontextobjektet som returneras här kan vara detsamma som det ursprungliga objektet som hämtades från GetOriginalObject. Om en nyckel finns på en överordnad modell och det finns en kontextjusterare som är associerad med den överordnade modellen är det ursprungliga objektet det instansobjekt där GetKeyReference eller EnumerateKeyReferences anropades. Kontextobjektet skulle vara det som kommer från den slutliga kontextjusteringen mellan det ursprungliga objektet och den överordnade modellen som innehåller nyckeln som den här nyckelreferensen är en referens till. Om det inte finns några kontextjusteringar är det ursprungliga objektet och kontextobjektet identiska.
GetKey-metoden för en nyckelreferens fungerar som GetKey-metoden på IModelObject skulle göra. Den returnerar värdet för den underliggande nyckeln och eventuella metadata som är associerade med nyckeln. Om värdet för nyckeln råkar vara en egenskapsåtkomst returnerar detta egenskapsåtkomstorn (IModelPropertyAccessor) i en IModelObject. Den här metoden anropar inte de underliggande GetValue- eller SetValue-metoderna i egenskapsåtkomstorn.
Metoden GetKeyValue på en nyckelreferens fungerar som metoden GetKeyValue på IModelObject. Den returnerar värdet för den underliggande nyckeln och eventuella metadata som är associerade med nyckeln. Om värdet för nyckeln råkar vara en egenskapsåtkomst anropas den underliggande GetValue-metoden i egenskapsåtkomstorn automatiskt.
SetKey-metoden för en nyckelreferens fungerar som SetKey-metoden på IModelObject. Den tilldelar värdet för nyckeln. Om den ursprungliga nyckeln var en egenskapsåtkomst ersätter detta egenskapsåtkomstorn. Metoden SetValue anropas inte i egenskapsåtkomstorn.
Metoden SetKeyValue på en nyckelreferens fungerar som metoden SetKeyValue på IModelObject. Den tilldelar värdet för nyckeln. Om den ursprungliga nyckeln var en egenskapsåtkomst anropas den underliggande SetValue-metoden i egenskapsåtkomstorn i stället för att ersätta själva egenskapsåtkomsten.
Metoden OverrideContextObject (endast i IModelKeyReference2) är en avancerad metod som används för att permanent ändra kontextobjektet som den här nyckelreferensen skickar till någon underliggande egenskapsåtkomstleverantörs GetValue- eller SetValue-metoder. Objektet som skickas till den här metoden returneras också från ett anrop till GetContextObject. Den här metoden kan användas av skriptprovidrar för att replikera vissa dynamiska språkbeteenden. De flesta klienter bör inte anropa den här metoden.
kontextobjekt: IDebugHostContext
Kontextobjekt är ogenomskinliga informationsblobar som felsökningsvärden (i samarbete med datamodellen) associerar med varje objekt. Den kan innehålla saker som processkontexten eller adressutrymmet som informationen kommer från osv. Ett kontextobjekt är en implementering av IDebugHostContext i en IModelObject. Observera att IDebugHostContext är ett värddefinierat gränssnitt. En klient implementerar aldrig det här gränssnittet.
Mer information om kontextobjekt finns i Felsökningsdatamodell C++ Värdgränssnitt i Felsökningsdatamodell C++-gränssnitt.
Data Model Manager
Kärngränssnittet till datamodellhanteraren, IDataModelManager2 (eller den tidigare IDataModelManager) definieras på följande sätt:
DECLARE_INTERFACE_(IDataModelManager2, IDataModelManager)
{
//
// IDataModelManager:
//
STDMETHOD(Close)() PURE;
STDMETHOD(CreateNoValue)(_Out_ IModelObject** object) PURE;
STDMETHOD(CreateErrorObject)(_In_ HRESULT hrError, _In_opt_ PCWSTR pwszMessage, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(CreateTypedObject)(_In_opt_ IDebugHostContext* context, _In_ Location objectLocation, _In_ IDebugHostType* objectType, _COM_Errorptr_ IModelObject** object) PURE;
STDMETHOD(CreateTypedObjectReference)(_In_opt_ IDebugHostContext* context, _In_ Location objectLocation, _In_ IDebugHostType* objectType, _COM_Errorptr_ IModelObject** object) PURE;
STDMETHOD(CreateSyntheticObject)(_In_opt_ IDebugHostContext* context, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(CreateDataModelObject)(_In_ IDataModelConcept* dataModel, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(CreateIntrinsicObject)(_In_ ModelObjectKind objectKind, _In_ VARIANT* intrinsicData, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(CreateTypedIntrinsicObject)(_In_ VARIANT* intrinsicData, _In_ IDebugHostType* type, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(GetModelForTypeSignature)(_In_ IDebugHostTypeSignature* typeSignature, _Out_ IModelObject** dataModel) PURE;
STDMETHOD(GetModelForType)(_In_ IDebugHostType* type, _COM_Outptr_ IModelObject** dataModel, _COM_Outptr_opt_ IDebugHostTypeSignature** typeSignature, _COM_Outptr_opt_ IDebugHostSymbolEnumerator** wildcardMatches) PURE;
STDMETHOD(RegisterModelForTypeSignature)(_In_ IDebugHostTypeSignature* typeSignature, _In_ IModelObject* dataModel) PURE;
STDMETHOD(UnregisterModelForTypeSignature)(_In_ IModelObject* dataModel, _In_opt_ IDebugHostTypeSignature* typeSignature) PURE;
STDMETHOD(RegisterExtensionForTypeSignature)(_In_ IDebugHostTypeSignature* typeSignature, _In_ IModelObject* dataModel) PURE;
STDMETHOD(UnregisterExtensionForTypeSignature)(_In_ IModelObject* dataModel, _In_opt_ IDebugHostTypeSignature* typeSignature) PURE;
STDMETHOD(CreateMetadataStore)(_In_opt_ IKeyStore* parentStore, _COM_Outptr_ IKeyStore** metadataStore) PURE;
STDMETHOD(GetRootNamespace)(_COM_Outptr_ IModelObject** rootNamespace) PURE;
STDMETHOD(RegisterNamedModel)(_In_ PCWSTR modelName, _In_ IModelObject *modeObject) PURE;
STDMETHOD(UnregisterNamedModel)(_In_ PCWSTR modelName) PURE;
STDMETHOD(AcquireNamedModel)(_In_ PCWSTR modelName, _COM_Outptr_ IModelObject **modelObject) PURE;
//
// IDataModelManager2:
//
STDMETHOD(AcquireSubNamespace)(_In_ PCWSTR modelName, _In_ PCWSTR subNamespaceModelName, _In_ PCWSTR accessName, _In_opt_ IKeyStore *metadata, _COM_Outptr_ IModelObject **namespaceModelObject) PURE;
STDMETHOD(CreateTypedIntrinsicObjectEx)(_In_opt_ IDebugHostContext* context, _In_ VARIANT* intrinsicData, _In_ IDebugHostType* type, _COM_Outptr_ IModelObject** object) PURE;
}
Hanteringsmetoder
Följande uppsättning metoder används av programmet (t.ex. felsökningsprogram) som är värd för datamodellen.
STDMETHOD(Close)() PURE;
Metoden Stäng anropas på datamodellhanteraren av ett program (t.ex. felsökningsprogram) som är värd för datamodellen för att starta avstängningsprocessen för datamodellhanteraren. En värd för datamodellen som inte använder metoden Close innan den slutliga referensen släpps i datamodellhanteraren kan orsaka odefinierat beteende, inklusive, men inte begränsat till, betydande läckor av hanteringsinfrastrukturen för datamodellen.
Objektskapande/Boxningsmetoder
Följande uppsättning metoder används för att skapa nya objekt eller för att boxa värden till en IModelObject – datamodellens kärngränssnitt.
STDMETHOD(CreateNoValue)(_Out_ IModelObject** object) PURE;
STDMETHOD(CreateErrorObject)(_In_ HRESULT hrError, _In_opt_ PCWSTR pwszMessage, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(CreateTypedObject)(_In_opt_ IDebugHostContext* context, _In_ Location objectLocation, _In_ IDebugHostType* objectType, _COM_Errorptr_ IModelObject** object) PURE;
STDMETHOD(CreateTypedObjectReference)(_In_opt_ IDebugHostContext* context, _In_ Location objectLocation, _In_ IDebugHostType* objectType, _COM_Errorptr_ IModelObject** object) PURE;
STDMETHOD(CreateSyntheticObject)(_In_opt_ IDebugHostContext* context, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(CreateDataModelObject)(_In_ IDataModelConcept* dataModel, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(CreateIntrinsicObject)(_In_ ModelObjectKind objectKind, _In_ VARIANT* intrinsicData, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(CreateTypedIntrinsicObject)(_In_ VARIANT* intrinsicData, _In_ IDebugHostType* type, _COM_Outptr_ IModelObject** object) PURE;
STDMETHOD(CreateMetadataStore)(_In_opt_ IKeyStore* parentStore, _COM_Outptr_ IKeyStore** metadataStore) PURE;
STDMETHOD(CreateTypedIntrinsicObjectEx)(_In_opt_ IDebugHostContext* context, _In_ VARIANT* intrinsicData, _In_ IDebugHostType* type, _COM_Outptr_ IModelObject** object) PURE;
Metoden CreateNoValue skapar ett "inget värde"-objekt, rutor det i en IModelObject och returnerar det. Det returnerade modellobjektet har en typ av ObjectNoValue.
Ett "inget värde"-objekt har flera semantiska betydelser:
- (Beroende på språk) kan det anses vara den semantiska motsvarigheten till void, null eller undefined
- En egenskapsåtkomstleverantörs GetValue-metod som returnerar framgång och ett resulterande "inget värde"-objekt indikerar att den specifika egenskapen inte har något värde för den angivna instansen och bör behandlas som om egenskapen inte fanns för den specifika instansen.
- Datamodellmetoder som inte semantiskt har ett returvärde använder detta som en sentinel för att indikera detta (som en metod måste returnera en giltig IModelObject).
Metoden CreateErrorObject skapar ett "felobjekt". Datamodellen har inte begreppet undantag och undantagsflöde. Felet kommer från en egenskap/metod på två sätt:
- En enda felande HRESULT utan utökad felinformation. Antingen finns det ingen mer information som kan ges för felet eller så är själva felet självförklarande från den returnerade HRESULT.
- En enda felande HRESULT i kombination med utökad felinformation. Den utökade felinformationen är ett felobjekt som returneras i utdataargumentet för egenskapen/metoden.
Metoden CreateTypedObject är den metod som gör att en klient kan skapa en representation av ett internt/språkobjekt i adressutrymmet för ett felsökningsmål. Om typen av det nyligen skapade objektet (enligt argumentet objectType) matchar en eller flera typsignaturer som registrerats med datamodellhanteraren som antingen kanoniska visualiserare eller tillägg, kopplas de matchande datamodellerna automatiskt till det skapade instansobjektet innan det returneras till anroparen.
Metoden CreateTypedObjectReference liknar metoden CreateTypedObject semantiskt, förutom att den skapar en referens till den underliggande inbyggda/språkkonstruktionen. Den skapade referensen är ett objekt som har en typ av ObjectTargetObjectReference. Det är inte en intern referens eftersom det underliggande språket kan stödja (t.ex. en C++ & eller &&). Det är fullt möjligt att ha en ObjectTargetObjectReference till en C++-referens. Ett objekt av typen ObjectTargetObjectReference kan konverteras till det underliggande värdet med hjälp av dereference-metoden på IModelObject. Referensen kan också skickas till den underliggande värdens uttrycksutvärdering för att tilldela tillbaka till värdet på ett lämpligt språk.
Metoden CreateSyntheticObject skapar ett tomt datamodellobjekt – en ordlista med nyckel/värde/metadatatupplar och begrepp. Vid tidpunkten för skapandet finns det inga nycklar eller begrepp i objektet. Det är en ren skiffer för anroparen att använda.
Metoden CreateDataModelObject är ett enkelt hjälpomslutningsprogram för att skapa objekt som är datamodeller , det villa är objekt som ska kopplas som överordnade modeller till andra objekt. Alla sådana objekt måste ha stöd för datamodellkonceptet via IDataModelConcept. Den här metoden skapar ett nytt tomt syntetiskt objekt utan explicit kontext och lägger till den inpassade IDataModelConcept som det nyligen skapade objektets implementering av datamodellkonceptet. Detta kan på liknande sätt utföras med anrop till CreateSyntheticObject och SetConcept.
Metoden CreateIntrinsicObject är metoden som rutor in inbyggda värden i IModelObject. Anroparen placerar värdet i en COM VARIANT och anropar den här metoden. Datamodellhanteraren returnerar en IModelObject som representerar objektet. Observera att den här metoden också används för att boxa grundläggande IUnknown-baserade typer: egenskapsåtkomst, metoder, kontexter osv. I sådana fall anger metoden objectKind vilken typ av IUnknown-baserad konstruktion objektet representerar och fältet punkVal för den överförda varianten är den härledda typen IUnknown. Typen måste vara statiskt gjutbar för rätt modellgränssnitt (t.ex. IModelPropertyAccessor, IModelMethod, IDebugHostContext osv.) i processen. Varianttyperna som stöds av den här metoden är VT_UI1, VT_I1, VT_UI2, VT_I2, VT_UI4, VT_I4, VT_UI8, VT_I8, VT_R4, VT_R8, VT_BOOL, VT_BSTR och VT_UNKNOWN (för en specialiserad uppsättning härledda IUnknown-typer som anges av uppräkningen ModelObjectKind.
Metoden CreateTypedintrinsicObject liknar metoden CreateIntrinsicObject, förutom att den tillåter att en in-/språktyp associeras med data och transporteras tillsammans med det boxade värdet. Detta gör att datamodellen kan representera konstruktioner som inbyggda uppräkningstyper (som helt enkelt är VT_UI* eller VT_I* värden). Pekartyper skapas också med den här metoden. En intern pekare i datamodellen är en noll utökad 64-bitars kvantitet som representerar en förskjutning till det virtuella adressutrymmet för felsökningsmålet. Den är rutad i en VT_UI8 och skapas med den här metoden och en typ som anger en in-/språkpekare.
Metoden CreateMetadataStore skapar ett nyckelarkiv – en förenklad container med nyckel/värde/metadatatupplar – som används för att lagra metadata som kan associeras med egenskaper och en mängd andra värden. Ett metadatalager kan ha en enda överordnad (som i sin tur kan ha en enda överordnad). Om en viss metadatanyckel inte finns i ett visst arkiv kontrolleras dess överordnade. De flesta metadatalager har inga överordnade. Det ger dock ett enkelt sätt att dela vanliga metadata.
Metoden CreateTypedIntrinsicObjectEx liknar semantiskt metoden CreateTypedIntrinsicObject. Den enda skillnaden mellan de två är att den här metoden tillåter anroparen att ange den kontext där de inbyggda data är giltiga. Om ingen kontext skickas anses data vara giltiga oavsett kontext som ärvs från typargumentet (hur CreateTypedIntrinsicObject beter sig). Detta gör det möjligt att skapa inskrivna pekarvärden i felsökningsmålet som kräver mer specifik kontext än vad som kan ärvas från typen.
Extensibility/Registration Methods Följande uppsättning metoder hanterar utökningsmekanismen för datamodellen, vilket gör att en klient kan utöka eller registrera befintliga modeller eller be datamodellen att automatiskt koppla en viss överordnad modell på interna typer som matchar ett visst kriterium.
STDMETHOD(GetModelForTypeSignature)(_In_ IDebugHostTypeSignature* typeSignature, _Out_ IModelObject** dataModel) PURE;
STDMETHOD(GetModelForType)(_In_ IDebugHostType* type, _COM_Outptr_ IModelObject** dataModel, _COM_Outptr_opt_ IDebugHostTypeSignature** typeSignature, _COM_Outptr_opt_ IDebugHostSymbolEnumerator** wildcardMatches) PURE;
STDMETHOD(RegisterModelForTypeSignature)(_In_ IDebugHostTypeSignature* typeSignature, _In_ IModelObject* dataModel) PURE;
STDMETHOD(UnregisterModelForTypeSignature)(_In_ IModelObject* dataModel, _In_opt_ IDebugHostTypeSignature* typeSignature) PURE;
STDMETHOD(RegisterExtensionForTypeSignature)(_In_ IDebugHostTypeSignature* typeSignature, _In_ IModelObject* dataModel) PURE;
STDMETHOD(UnregisterExtensionForTypeSignature)(_In_ IModelObject* dataModel, _In_opt_ IDebugHostTypeSignature* typeSignature) PURE;
STDMETHOD(GetRootNamespace)(_COM_Outptr_ IModelObject** rootNamespace) PURE;
STDMETHOD(RegisterNamedModel)(_In_ PCWSTR modelName, _In_ IModelObject *modeObject) PURE;
STDMETHOD(UnregisterNamedModel)(_In_ PCWSTR modelName) PURE;
STDMETHOD(AcquireNamedModel)(_In_ PCWSTR modelName, _COM_Outptr_ IModelObject **modelObject) PURE;
Metoden GetModelForTypeSignature returnerar datamodellen som registrerades mot en viss typsignatur via ett tidigare anrop till metoden RegisterModelForTypeSignature. Datamodellen som returneras från den här metoden anses vara den kanoniska visualiseraren för alla typer som matchar signaturen för godkänd typ. Som kanonisk visualiserare tar datamodellen över visningen av typen. Visningsmotorer döljer som standard inbyggda/språkkonstruktioner av objektet till förmån för vyn av objektet som presenteras av datamodellen.
Metoden GetModelForType returnerar datamodellen som är den kanoniska visualiseraren för en viss typinstans. I själva verket hittar den här metoden den bästa matchande typsignaturen som registrerades med ett tidigare anrop till metoden RegisterModelForTypeSignature och returnerar den associerade datamodellen.
Metoden RegisterModelForTypeSignature är den primära metod som en anropare använder för att registrera en kanonisk visualiserare för en viss typ (eller uppsättning av typer). En kanonisk visualiserare är en datamodell som i själva verket tar över visningen av en viss typ (eller uppsättning av typer). I stället för den inbyggda/språkvy av typen som visas i något felsökningsprograms användargränssnitt, visas vyn av typen som presenteras av den registrerade datamodellen (tillsammans med ett sätt att komma tillbaka till vyn native/language för en användare som önskar det).
UnregisterModelForTypeSignature
Metoden UnregisterModelForTypeSignature ångrar ett tidigare anrop till metoden RegisterModelForTypeSignature. Den här metoden kan antingen ta bort en viss datamodell som kanonisk visualiserare för typer som matchar en viss typsignatur eller ta bort en viss datamodell som kanonisk visualiserare för varje typsignatur under vilken datamodellen är registrerad.
RegisterExtensionForTypeSignature
Metoden RegisterExtensionForTypeSignature liknar metoden RegisterModelForTypeSignature med en viktig skillnad. Datamodellen som skickas till den här metoden är inte den kanoniska visualiseraren för någon typ och den tar inte över visningen av den inbyggda/språkvyn av den typen. Datamodellen som skickas till den här metoden läggs automatiskt till som överordnad till valfri konkret typ som matchar den angivna typsignaturen. Till skillnad från metoden RegisterModelForTypeSignature finns det ingen gräns för identiska eller tvetydiga typsignaturer som registreras som tillägg till en viss typ (eller uppsättning av typer). Varje tillägg vars typsignatur matchar en viss instans av betongtyp gör att datamodellen som registreras via den här metoden automatiskt kopplas till nyligen skapade objekt som överordnade modeller. Detta innebär i själva verket att ett godtyckligt antal klienter kan utöka en typ (eller uppsättning typer) med nya fält eller funktioner.
UnregisterExtensionForTypeSignature
Metoden UnregisterExtensionForTypeSignature ångrar ett tidigare anrop till RegisterExtensionForTypeSignature. Den avregistrerar en viss datamodell som ett tillägg för antingen en viss typsignatur eller som ett tillägg för alla typsignaturer som datamodellen registrerades mot.
Metoden GetRootNamespace returnerar datamodellens rotnamnområde. Det här är ett objekt som datamodellen hanterar och som felsökningsvärden placerar vissa objekt i.
Metoden RegisterNamedModel registrerar en viss datamodell under ett välkänt namn så att den kan hittas av klienter som vill utöka den. Det här är det primära syftet med API:et – att publicera en datamodell som något som kan utökas genom att hämta modellen som är registrerad under det här välkända namnet och lägga till en överordnad modell i den.
Metoden UnregisterNamedModel ångrar ett tidigare anrop till RegisterNamedModel. Den tar bort associationen mellan en datamodell och ett namn som den kan letas upp under.
En anropare som vill utöka en datamodell som är registrerad under ett visst namn anropar metoden AcquireNamedModel för att hämta objektet för den datamodell som de vill utöka. Den här metoden returnerar den datamodell som registrerades via ett tidigare anrop till metoden RegisterNamedModel. Eftersom det primära syftet med metoden AcquireNamedModel är att utöka modellen har den här metoden ett särskilt beteende om ingen modell har registrerats under det angivna namnet ännu. Om ingen modell har registrerats under det angivna namnet ännu skapas ett stub-objekt, registreras tillfälligt under det angivna namnet och returneras till anroparen. När den verkliga datamodellen registreras via ett anrop till metoden RegisterNamedModel görs alla ändringar som har gjorts i stub-objektet i praktiken till den verkliga modellen. Detta tar bort många problem med belastningsordningsberoenden från komponenter som utökar varandra.
hjälpmetoder
Följande metoder är allmänna hjälpmetoder som hjälper dig att utföra komplexa åtgärder på objekt i datamodellen. Även om det är möjligt att utföra dessa åtgärder via andra metoder i datamodellen eller dess objekt, gör dessa bekvämlighetsmetoder det betydligt enklare:
STDMETHOD(AcquireSubNamespace)(_In_ PCWSTR modelName, _In_ PCWSTR subNamespaceModelName, _In_ PCWSTR accessName, _In_opt_ IKeyStore *metadata, _COM_Outptr_ IModelObject **namespaceModelObject) PURE;
Metoden AcquireSubNamespace hjälper dig att skapa något som mer traditionellt kan se ut som ett språknamnområde än ett nytt objekt på ett dynamiskt språk. Om till exempel en anropare vill kategorisera egenskaper för ett processobjekt för att göra processobjektet mer organiserat och egenskaperna blir lättare att identifiera, skulle en metod för att göra detta vara att skapa ett underobjekt för varje kategori i processobjektet och placera dessa egenskaper inuti objektet.
Se även
Det här avsnittet är en del av en serie som beskriver de gränssnitt som är tillgängliga från C++, hur du använder dem för att skapa ett C++-baserat felsökningstillägg och hur du använder andra datamodellkonstruktioner (t.ex. JavaScript eller NatVis) från ett C++-datamodelltillägg.
Felsökningsdatamodell C++ Översikt
Felsökarens C++-gränssnitt för datamodell
Felsökningsdatamodell C++ Ytterligare gränssnitt