Begrepp för felsökningsdatamodell C++

Det här avsnittet beskriver begreppen i felsökningsprogrammet C++ Data Model .

Begrepp i datamodellen

Syntetiska objekt i datamodellen är i praktiken två saker:

  • En ordlista med nyckel/värde/metadatatupplar.
  • En uppsättning begrepp (gränssnitt) som stöds av datamodellen. Begrepp är gränssnitt som en klient (i motsats till datamodellen) implementerar för att tillhandahålla en angiven uppsättning semantiska beteenden. Den uppsättning begrepp som stöds för närvarande visas här.
Konceptgränssnitt Beskrivning
IDataModelConcept Konceptet är en föräldramodell. 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.
VisningsbarSträngKoncept 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.
IDynamisktKonceptLeverantörKoncept 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.

Datamodellkonceptet: IDataModelConcept

Alla modellobjekt som är kopplade till ett annat modellobjekt som en överordnad modell måste ha direkt stöd för datamodellkonceptet. Datamodellkonceptet kräver stöd för ett gränssnitt, IDataModelConcept definierat på följande sätt.

DECLARE_INTERFACE_(IDataModelConcept, IUnknown)
{
    STDMETHOD(InitializeObject)(_In_ IModelObject* modelObject, _In_opt_ IDebugHostTypeSignature* matchingTypeSignature, _In_opt_ IDebugHostSymbolEnumerator* wildcardMatches) PURE;
    STDMETHOD(GetName)(_Out_ BSTR* modelName) PURE;
}

InitializeObject

En datamodell kan registreras som kanonisk visualiserare eller som ett tillägg för en viss intern typ via datamodellhanterarens RegisterModelForTypeSignature- eller RegisterExtensionForTypeSignature-metoder. När en modell registreras via någon av dessa metoder kopplas datamodellen automatiskt som en överordnad modell till alla interna objekt vars typ matchar signaturen som skickades i registreringen. Vid den punkt där den kopplingen görs automatiskt, anropas metoden InitializeObject på datamodellen. Instansobjektet skickas tillsammans med typsignaturen som orsakade anknytningen och en uppräknare som genererar de typinstanser (i linjär ordning) som matchade eventuella jokertecken i typsignaturen. Implementeringen av datamodellen kan använda det här metodanropet för att initiera eventuella cacheminnen som krävs.

GetName

Om en viss datamodell registreras under ett standardnamn via metoden RegisterNamedModel måste den registrerade datamodellens IDataModelConcept-gränssnitt returnera det namnet från den här metoden. Observera att det är helt legitimt att en modell registreras under flera namn (standard eller bästa bör returneras här). En modell kan vara helt namnlös (så länge den inte är registrerad under ett namn). I sådana fall bör metoden GetName returnera E_NOTIMPL.

Strängvisningskonceptet: IStringDisplayableConcept

Ett objekt som vill tillhandahålla en strängkonvertering för visningsändamål kan implementera strängvisningskonceptet genom implementering av gränssnittet IStringDisplayableConcept. Gränssnittet definieras på följande sätt:

DECLARE_INTERFACE_(IStringDisplayableConcept, IUnknown)
{
    STDMETHOD(ToDisplayString)(_In_ IModelObject* contextObject, _In_opt_ IKeyStore* metadata, _Out_ BSTR* displayString) PURE;
}

ToDisplayString

Metoden ToDisplayString anropas när en klient vill konvertera ett objekt till en sträng som ska visas (till konsolen, i användargränssnittet osv.). En sådan strängkonvertering bör inte användas för ytterligare programmeringsmanipulering. Själva strängkonverteringen kan påverkas djupt av de metadata som skickas till anropet. En strängkonvertering bör göra varje försök att uppfylla nycklarna PreferredRadix och PreferredFormat.

Det itererbara konceptet: IIterableConcept och IModelIterator

Ett objekt som är en container med andra objekt och vill uttrycka möjligheten att iterera över de inneslutna objekten kan stödja det iterbara konceptet genom en implementering av gränssnitten IIterableConcept och IModelIterator. Det finns ett mycket viktigt samband mellan stöd för det iterbara konceptet och stöd för det indexerbara konceptet. Ett objekt som stöder slumpmässig åtkomst till de inneslutna objekten kan stödja det indexerbara konceptet utöver det iterbara konceptet. I det här fallet måste de itererade elementen också skapa ett standardindex som när de skickas till det indexerbara begreppet refererar till samma objekt. Om den här invarianten inte uppfylls resulterar det i ett odefinierat beteende i felsökningsvärden.

IIterableConcept definieras på följande sätt:

DECLARE_INTERFACE_(IIterableConcept, IUnknown)
{
    STDMETHOD(GetDefaultIndexDimensionality)(_In_ IModelObject* contextObject, _Out_ ULONG64* dimensionality) PURE;
    STDMETHOD(GetIterator)(_In_ IModelObject* contextObject, _Out_ IModelIterator** iterator) PURE;
}

IModelIterator-konceptet definieras på följande sätt:

DECLARE_INTERFACE_(IModelIterator, IUnknown)
{
   STDMETHOD(Reset)() PURE;
   STDMETHOD(GetNext)(_COM_Errorptr_ IModelObject** object, _In_ ULONG64 dimensions, _Out_writes_opt_(dimensions) IModelObject** indexers, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
}

IIterableConcept's GetDefaultIndexDimensionality

Metoden GetDefaultIndexDimensionality returnerar antalet dimensioner till standardindexet. Om ett objekt inte kan indexeras bör den här metoden returnera 0 och lyckas (S_OK). Alla objekt som returnerar ett värde som inte är noll från den här metoden deklarerar stöd för ett protokollkontrakt som anger:

  • Objektet stöder det indexerbara konceptet via stöd för IIndexableConcept
  • Metoden GetNext för IModelIterator som returneras från metoden GetIterator i det iterbara konceptet returnerar ett unikt standardindex för varje producerat element. Ett sådant index har det antal dimensioner som anges här.
  • Om du skickar indexen som returneras från metoden GetNext för IModelIterator till metoden GetAt i det indexerbara konceptet (IIndexableConcept) refererar du till samma objekt som GetNext skapade. Samma värde returneras.

IIterableConcepts GetIterator

Metoden GetIterator i det iterbara konceptet returnerar ett iteratorgränssnitt som kan användas för att iterera objektet. Den returnerade iteratorn måste komma ihåg det kontextobjekt som skickades till metoden GetIterator. Den skickas inte till metoderna i själva iteratorn.

Återställ IModelIterator

Metoden Återställ i en iterator som returneras från det iterbara konceptet återställer iteratorns position till den plats där den var när iteratorn först skapades (före det första elementet). Det rekommenderas starkt att iteratorn stöder återställningsmetoden, men det krävs inte. En iterator kan motsvara en C++-indata iterator och endast tillåta en enda vidarebefordran iteration. I sådana fall kan återställningsmetoden misslyckas med E_NOTIMPL.

IModelIterators GetNext

Metoden GetNext flyttar iteratorn framåt och hämtar nästa itererade element. Om objektet är indexerbart förutom att det går att iterera och detta anges av argumentet GetDefaultIndexDimensionality som returnerar ett värde som inte är noll, kan den här metoden eventuellt returnera standardindexen för att återgå till det producerade värdet från indexeraren. Observera att en anropare kan välja att skicka 0/nullptr och inte hämta några index. Det anses olagligt för anroparen att begära partiella index (t.ex. mindre än det antal som produceras av GetDefaultIndexDimensionality).

Om iteratorn har flyttats framåt, men det uppstod ett fel vid läsning av värdet för det itererade elementet, kan metoden returnera ett fel OCH fylla "objekt" med ett felobjekt. I slutet av iterationen av de inneslutna elementen returnerar iteratorn E_BOUNDS från metoden GetNext. Alla efterföljande anrop (om det inte har skett ett mellanliggande återställningsanrop) returnerar också E_BOUNDS.

Indexerbart koncept: IIndexableConcept

Ett objekt som vill ge slumpmässig åtkomst till en uppsättning innehåll kan stödja det indexerbara konceptet via stöd för gränssnittet IIndexableConcept. De flesta objekt som är indexerbara kan även itereras genom stöd för det iterbara konceptet. Detta krävs dock inte. Om det stöds finns det en viktig relation mellan iteratorn och indexeraren. Iteratorn måste ha stöd för GetDefaultIndexDimensionality, returnera ett värde som inte är noll från den metoden och stödja kontraktet som dokumenteras där. Indexerarens konceptgränssnitt definieras på följande sätt:

DECLARE_INTERFACE_(IIndexableConcept, IUnknown)
{
    STDMETHOD(GetDimensionality)(_In_ IModelObject* contextObject, _Out_ ULONG64* dimensionality) PURE;
    STDMETHOD(GetAt)(_In_ IModelObject* contextObject, _In_ ULONG64 indexerCount, _In_reads_(indexerCount) IModelObject** indexers, _COM_Errorptr_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
    STDMETHOD(SetAt)(_In_ IModelObject* contextObject, _In_ ULONG64 indexerCount, _In_reads_(indexerCount) IModelObject** indexers, _In_ IModelObject *value) PURE;
}

Ett exempel på hur du använder indexeraren (och dess samspel med iteratorn) visas nedan. I det här exemplet itereras innehållet i en indexerbar container och indexeraren används för att återgå till det värde som just returnerats. Även om den åtgärden är funktionellt värdelös som den är skriven, visar den hur dessa gränssnitt interagerar. Observera att exemplet nedan inte hanterar minnesallokeringsfel. Det förutsätter att en ny genererar (vilket kan vara ett dåligt antagande beroende på miljön där koden finns – COM-metoderna för datamodellen kan inte ha C++-undantag som undantag):

ComPtr<IModelObject> spObject;

//
// Assume we have gotten some object in spObject that is iterable (e.g.: an object which represents a std::vector<SOMESTRUCT>)
//
ComPtr<IIterableConcept> spIterable;
ComPtr<IIndexableConcept> spIndexer;
if (SUCCEEDED(spObject->GetConcept(__uuidof(IIterableConcept), &spIterable, nullptr)) &&
    SUCCEEDED(spObject->GetConcept(__uuidof(IIndexableConcept), &spIndexable, nullptr)))
{
    ComPtr<IModelIterator> spIterator;

    //
    // Determine how many dimensions the default indexer is and allocate the requisite buffer.
    //
    ULONG64 dimensions;
    if (SUCCEEDED(spIterable->GetDefaultIndexDimensionality(spObject.Get(), &dimensions)) && dimensions > 0 &&
        SUCCEEDED(spIterable->GetIterator(spObject.Get(), &spIterator)))
    {
        std::unique_ptr<ComPtr<IModelObject>[]> spIndexers(new ComPtr<IModelObject>[dimensions]);

        //
        // We have an iterator.  Error codes have semantic meaning here.  E_BOUNDS indicates the end of iteration.  E_ABORT indicates that
        // the debugger host or application is trying to abort whatever operation is occurring.  Anything else indicates
        // some other error (e.g.: memory read failure) where the iterator MIGHT still produce values.
        //
        for(;;)
        {
            ComPtr<IModelObject> spContainedStruct;
            ComPtr<IKeyStore> spContainedMetadata;

            //
            // When we fetch the value from the iterator, it will pass back the default indices.
            //
            HRESULT hr = spIterable->GetNext(&spContainedStruct, dimensions, reinterpret_cast<IModelObject **>(spIndexers.get()), &spContainedMetadata);
            if (hr == E_BOUNDS || hr == E_ABORT)
            {
                break;
            }

            if (FAILED(hr))
            {
                //
                // Decide how to deal with failure to fetch an element.  Note that spContainedStruct *MAY* contain an error object
                // which has detailed information about why the failure occurred (e.g.: failure to read memory at address X).
                //
            }

            //
            // Use the indexer to get back to the same value.  We already have them, so there isn't much functional point to this.  It simply
            // highlights the interplay between iterator and indexer.
            //
            ComPtr<IModelObject> spIndexedStruct;
            ComPtr<IKeyStore> spIndexedMetadata;

            if (SUCCEEDED(spIndexer->GetAt(spObject.Get(), dimensions, reinterpret_cast<IModelObject **>(spIndexers.get()), &spIndexedStruct, &spIndexedMetadata)))
            {
                //
                // spContainedStruct and spIndexedStruct refer to the same object.  They may not have interface equality.
                // spContainedMetadata and spIndexedMetadata refer to the same metadata store with the same contents.  They may not have interface equality.
                //
            }
        }
    }
}

GetDimensionality

Metoden GetDimensionality returnerar antalet dimensioner som objektet indexeras i. Observera att om objektet är både iterbart och indexerbart måste implementeringen av GetDefaultIndexDimensionality överensstämma med implementeringen av GetDimensionality om hur många dimensioner indexeraren har.

GetAt

Metoden GetAt hämtar värdet vid ett visst N-dimensionellt index inifrån det indexerade objektet. En indexerare med N-dimensioner där N är värdet som returneras från GetDimensionality måste stödjas. Observera att ett objekt kan indexeras i olika domäner efter olika typer (t.ex. indexerbara via både ordningstal och strängar). Om indexet ligger inom intervallet (eller inte kunde nås) returnerar metoden ett fel. I sådana fall kan dock utdataobjektet fortfarande vara inställt på ett felobjekt.

SetAt

Metoden SetAt försöker ange värdet till ett visst N-dimensionellt index inifrån det indexerade objektet. En indexerare med N-dimensioner där N är värdet som returneras från GetDimensionality måste stödjas. Observera att ett objekt kan indexeras i olika domäner efter olika typer (t.ex. indexerbara via både ordningstal och strängar). Vissa indexerare är skrivskyddade. I sådana fall returneras E_NOTIMPL från valfritt anrop till Metoden SetAt.

Det föredragna körtidstypkonceptet: IPreferredRuntimeTypeConcept

En värddator för felsökning kan förfrågas om att bestämma det verkliga körningens typ av ett objekt från en statisk typ som finns i symbolisk information. Den här konverteringen kan baseras på helt korrekt information (t.ex. C++ RTTI) eller baseras på stark heuristik, till exempel formen på virtuella funktionstabeller i objektet. Vissa objekt kan dock inte konverteras från en statisk typ till en körningstidstyp eftersom de inte passar in i heuristiken för felsökningsvärd (t.ex. på grund av att de saknar RTTI eller virtuella funktionstabeller). I sådana fall kan en datamodell för ett objekt välja att åsidosätta standardbeteendet och deklarera att den vet mer om "körtidstypen" för ett objekt än vad felsökningsvärd kan förstå. Detta görs via det föredragna exekveringstypkonceptet och stöd för gränssnittet IPreferredRuntimeTypeConcept.

Gränssnittet IPreferredRuntimeTypeConcept deklareras på följande sätt:

DECLARE_INTERFACE_(IPreferredRuntimeTypeConcept, IUnknown)
{
    STDMETHOD(CastToPreferredRuntimeType)(_In_ IModelObject* contextObject, _COM_Errorptr_ IModelObject** object) PURE;
}

CastToPreferredRuntimeType

Metoden CastToPreferredRuntimeType anropas när en klient vill försöka konvertera från en instans av statisk typ till körningstypen för den instansen. Om objektet i fråga stöder det föredragna runtime-typ konceptet (via en av dess anslutna överordnade modeller) kommer den här metoden att anropas för att utföra konverteringen. Den här metoden kan antingen returnera det ursprungliga objektet (det finns ingen konvertering eller så gick det inte att analysera det), returnera en ny instans av körningstypen, misslyckas av icke-semantiska orsaker (t.ex. slut på minne) eller returnera E_NOT_SET. Felkoden E_NOT_SET är en mycket speciell felkod som anger för datamodellen att implementeringen inte vill förändra standardbeteendet och att datamodellen ska återgå till den analys som utförs av debugvärden (t.ex. RTTI-analys, undersökning av formen på de virtuella funktionstabellerna, osv.)

De dynamiska provider-koncepten: IDynamicKeyProviderConcept och IDynamicConceptProviderConcept

Även om själva datamodellen normalt hanterar nyckel- och koncepthantering för objekt, finns det tillfällen då begreppet är mindre än idealiskt. Särskilt när en klient vill skapa en brygga mellan datamodellen och något annat som verkligen är dynamiskt (t.ex. JavaScript) kan det vara värdefullt att ta över nyckel- och koncepthantering från implementeringen i datamodellen. Eftersom kärndatamodellen är den enda implementeringen av IModelObject görs detta i stället via en kombination av två begrepp: konceptet med dynamisk nyckelprovider och begreppet leverantör av dynamiska koncept. Även om det skulle vara typiskt att implementera båda eller inget av dem, finns det inget krav på detta.

Om båda implementeras måste konceptet med dynamisk nyckelprovider läggas till innan begreppet dynamisk konceptleverantör. Båda dessa begrepp är speciella. De vänder effektivt en växel på objektet som ändrar det från "statiskt hanterad" till "dynamiskt hanterad". Dessa begrepp kan bara anges om det inte finns några nycklar/begrepp som hanteras av datamodellen på objektet. När dessa begrepp har lagts till i ett objekt är åtgärden att göra detta oåterkallelig.

Det finns ytterligare en semantisk skillnad kring utökningsbarhet mellan en IModelObject som är en dynamisk konceptleverantör och en som inte är det. Dessa begrepp är avsedda att tillåta klienter att skapa bryggor mellan datamodellen och dynamiska språksystem som JavaScript. Datamodellen har ett begrepp för utökningsbarhet som skiljer sig något i grunden från system som JavaScript eftersom det finns ett träd med överordnade modeller snarare än en linjär kedja som JavaScript-prototypkedjan. För att möjliggöra en bättre relation till sådana system har en IModelObject som är en dynamisk konceptprovider en enda överordnad datamodell. Den överordnade datamodellen är en vanlig IModelObject som kan ha ett godtyckligt antal överordnade modeller, vilket är typiskt för datamodellen. Alla begäranden till den dynamiska konceptleverantören för att lägga till eller ta bort överordnade omdirigeras automatiskt till den enda överordnade. Från en utomståendes perspektiv ser det ut som om den dynamiska konceptleverantören har en normal trädstilkedja med överordnade modeller. Implementeraren av konceptet för den dynamiska konceptprovidern är det enda objektet (utanför kärndatamodellen) som är medvetet om det mellanliggande överordnade objektet. Den enda föräldern kan länkas mot det dynamiska språksystemet för att tillhandahålla en brygga (t.ex. placerad i JavaScript-prototypkedjan).

Begreppet dynamisk nyckelleverantör definieras på följande sätt:

DECLARE_INTERFACE_(IDynamicKeyProviderConcept, IUnknown)
{
    STDMETHOD(GetKey)(_In_ IModelObject *contextObject, _In_ PCWSTR key, _COM_Outptr_opt_result_maybenull_ IModelObject** keyValue, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata, _Out_opt_ bool *hasKey) PURE;
    STDMETHOD(SetKey)(_In_ IModelObject *contextObject, _In_ PCWSTR key, _In_ IModelObject *keyValue, _In_ IKeyStore *metadata) PURE;
    STDMETHOD(EnumerateKeys)(_In_ IModelObject *contextObject, _COM_Outptr_ IKeyEnumerator **ppEnumerator) PURE;
}

Begreppet leverantör av dynamiskt koncept definieras på följande sätt:

DECLARE_INTERFACE_(IDynamicConceptProviderConcept, IUnknown)
{
    STDMETHOD(GetConcept)(_In_ IModelObject *contextObject, _In_ REFIID conceptId, _COM_Outptr_result_maybenull_ IUnknown **conceptInterface, _COM_Outptr_opt_result_maybenull_ IKeyStore **conceptMetadata, _Out_ bool *hasConcept) PURE;
    STDMETHOD(SetConcept)(_In_ IModelObject *contextObject, _In_ REFIID conceptId, _In_ IUnknown *conceptInterface, _In_opt_ IKeyStore *conceptMetadata) PURE;
    STDMETHOD(NotifyParent)(_In_ IModelObject *parentModel) PURE;
    STDMETHOD(NotifyParentChange)(_In_ IModelObject *parentModel) PURE;
    STDMETHOD(NotifyDestruct)() PURE;
}

IDynamicKeyProviderConcepts GetKey

GetKey-metoden på en dynamisk nyckelleverantör är till stor del en åsidosättning av metoden GetKey på IModelObject. Den dynamiska nyckelprovidern förväntas returnera värdet för nyckeln och eventuella metadata som är associerade med den nyckeln. Om nyckeln inte finns (men inget annat fel inträffar) måste providern returnera false i parametern hasKey och lyckas med S_OK. Om det här anropet misslyckas anses det vara ett misslyckande att hämta en nyckel och stoppar uttryckligen sökningen efter nyckeln via den överordnade modellkedjan. Om du returnerar false i hasKey och lyckas kommer sökningen efter nyckeln att fortsätta. Observera att det är helt lagligt för GetKey att returnera en boxad egenskapsåtkomstor som nyckel. Detta skulle vara semantiskt identiskt med GetKey-metoden på IModelObject som returnerar en egenskapsaccessor.

IDynamicKeyProviderConcepts SetKey

SetKey-metoden på en dynamisk nyckelleverantör är i praktiken en åsidosättning av metoden SetKey i IModelObject. Detta anger en nyckel i den dynamiska providern. I praktiken handlar det om att skapa en ny egenskap på leverantören. Observera att en provider som inte stöder konceptet med skapande av expando-egenskaper bör returnera E_NOTIMPL här.

IDynamicKeyProviderConcepts EnumerateKeys

Metoden EnumerateKeys på en dynamisk nyckelleverantör är i själva verket en överskrivning av metoden EnumerateKeys i IModelObject. Detta räknar upp alla nycklar i den dynamiska providern. Den returnerade uppräknaren har flera begränsningar som måste uppfyllas av implementeringen:

  • Den måste fungera som ett anrop till EnumerateKeys och inte EnumerateKeyValues eller EnumerateKeyReferences. Den måste returnera nyckelvärdena utan att lösa några underliggande egenskapsåtkomstmetoder (om det finns ett sådant begrepp i providern).
  • Ur en enda dynamisk nyckelproviders perspektiv är det inte tillåtet att räkna upp flera nycklar med samma namn som är fysiskt distinkta nycklar. Detta kan inträffa på olika leverantörer som är kopplade via den överordnade modellkedjan, men det kan inte ske från en enda providers perspektiv.

IDynamicConceptProviderConcepts GetConcept

Metoden GetConcept på en dynamisk konceptprovider är i själva verket en åsidosättning av Metoden GetConcept i IModelObject. Den dynamiska konceptprovidern måste returnera ett gränssnitt för det efterfrågade konceptet om det finns samt eventuella metadata som är associerade med det konceptet. Om konceptet inte finns på providern måste det anges via ett falskt värde som returneras i hasConcept-argumentet och en lyckad retur. Det går inte att hämta konceptet och stoppar uttryckligen sökningen efter konceptet. Om du returnerar false för hasConcept fortsätter en lyckad kod sökningen efter konceptet via det överordnade modellträdet.

IDynamicConceptProviderConcepts SetConcept

Metoden SetConcept på en dynamisk konceptprovider är i själva verket en åsidosättning av Metoden SetConcept i IModelObject. Den dynamiska providern tilldelar konceptet. Detta kan göra objektet iterabelt, indexerbart, sträng konvertibelt osv. Observera att en provider som inte tillåter att begrepp skapas på den bör returnera E_NOPTIMPL här.

IDynamicConceptProviderConcepts NotifyParent

NotifyParent-anropet på en dynamisk konceptleverantör används av kärndatamodellen för att informera den dynamiska leverantören om den enda överordnade modellen som skapas för att överbrygga paradigmet "flera överordnade modeller" i datamodellen till mer dynamiska språk. All manipulering av den enskilda huvudmodellen orsakar ytterligare meddelanden till den dynamiska leverantören. Observera att återanropet görs omedelbart efter tilldelningen av begreppet dynamisk konceptleverantör.

IDynamicConceptProviderConcepts NotifyParentChange

Metoden NotifyParent på en dynamisk konceptprovider är ett återanrop som görs av kärndatamodellen när en statisk manipulering av objektets överordnade modell görs. För en viss överordnad modell som läggs till anropas den här metoden första gången när den överordnade modellen läggs till och en andra gång om/när den överordnade modellen tas bort.

IDynamicConceptProviderConcepts NotifyDestruct

Metoden NotifyDestruct på en dynamisk konceptprovider är en återanrop som görs av kärndatamodellen i början av förstörelsen av objektet som är en dynamisk konceptprovider. Det ger ytterligare rensningsmöjligheter för klienter som kräver det.

--

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.

Översikt över felsökningsdatamodellen C++

Felsökardatamodellens C++-gränssnitt

Debuggarens datamodell C++-objekt

Felsökningsdatamodellens C++ Ytterligare Gränssnitt

Felsökning av datamodell C++-skript