Debuggerdatenmodell-C++-Objekte

In diesem Thema wird beschrieben, wie Sie C++-Objekte des Debuggerdatenmodells verwenden und die Funktionen des Debuggers erweitern können.

Das Kerndebuggerobjektmodell

Eine der grundlegendsten, aber dennoch leistungsfähigsten Dinge am Datenmodell ist, dass es die Definition, was ein Objekt ist und wie man mit einem Objekt interagiert, standardisiert. Die IModelObject-Schnittstelle kapselt den Begriff eines Objekts – unabhängig davon, ob es sich bei diesem Objekt um eine ganze Zahl, einen Gleitkommawert, eine Zeichenfolge, einen komplexen Typ im Zieladressraum des Debuggers oder ein Debuggerkonzept wie den Begriff eines Prozesses oder eines Moduls handelt.

Es gibt mehrere verschiedene Dinge, die in einem IModelObject gehalten (oder in geschachtelt) werden können:

  • Systeminterne Werte : Ein IModelObject kann ein Container für eine Reihe grundlegender Typen sein: 8-, 16-, 32- oder 64-Bit-Ganzzahlen mit oder ohne Vorzeichen, Boolesche, Zeichenfolgen, Fehler oder der Begriff leer.

  • Native Objekte : Ein IModelObject kann einen komplexen Typ (gemäß Definition durch das Typsystem des Debuggers) innerhalb des Adressraums des Debuggers darstellen.

  • Synthetische Objekte : Ein IModelObject kann ein dynamisches Objekt sein– ein Wörterbuch, wenn Sie möchten: eine Sammlung von Schlüssel-Wert-/Metadatentupeln und eine Reihe von Konzepten , die Verhaltensweisen definieren, die nicht einfach durch Schlüssel-Wert-Paare dargestellt werden.

  • Eigenschaften : Ein IModelObject kann eine Eigenschaft darstellen: etwas, dessen Wert mit einem Methodenaufruf abgerufen oder geändert werden kann. Eine Eigenschaft in einem IModelObject ist effektiv eine IModelPropertyAccessor-Schnittstelle, die in einem IModelObject-Objekt geschachtelt ist.

  • Methoden : Ein IModelObject kann eine Methode darstellen: Etwas, das Sie mit einer Reihe von Argumenten aufrufen und einen Rückgabewert abrufen können. Eine Methode innerhalb eines IModelObject ist im Grunde eine IModelMethod-Schnittstelle, die in einem IModelObject-Objekt geschachtelt ist.

Erweiterbarkeit innerhalb des Objektmodells

Ein IModelObject ist kein isoliertes Objekt. Zusätzlich zur Darstellung eines der oben gezeigten Objekttypen hat jedes Objekt das Konzept einer Kette übergeordneter Datenmodelle. Diese Kette verhält sich ähnlich wie eine JavaScript-Prototypkette. Anstelle einer linearen Kette von Prototypen wie JavaScript definiert jedes Datenmodellobjekt eine lineare Kette übergeordneter Modelle. Jedes dieser übergeordneten Modelle verfügt wiederum über eine weitere lineare Kette eines eigenen Satzes von übergeordneten Elementen. Im Wesentlichen ist jedes Objekt eine Aggregation der Funktionen (Eigenschaften usw.) von sich selbst und jedem Objekt in dieser Struktur. Wenn eine bestimmte Eigenschaft abgefragt wird und das objekt, für das sie abgefragt wird, diese Eigenschaft nicht unterstützt, wird die Abfrage in linearer Reihenfolge an jedes übergeordnete Element übergeben. Dadurch wird ein Verhalten erstellt, bei dem die Suche nach einer Eigenschaft durch eine Tiefensuche der Aggregatstruktur aufgelöst wird.

Die Erweiterbarkeit innerhalb dieses Objektmodells ist sehr einfach, wenn man bedenkt, dass jedes Objekt ein Aggregat von sich selbst und der Struktur übergeordneter Modelle ist. Eine Erweiterung kann sich selbst in die Liste der übergeordneten Modelle für ein anderes Objekt einfügen. Dadurch wird das -Objekt erweitert . Auf diese Weise ist es möglich, allen Funktionen hinzuzufügen: einer bestimmten instance eines Objekts oder Werts, einem nativen Typ, dem Konzept des Debuggers, was ein Prozess oder Thread ist, oder sogar die Vorstellung von "allen iterierbaren Objekten".

Kontext, Kontext und Kontext : Dieser Zeiger, Der Adressraum und private Implementierungsdaten

Es gibt drei Kontextbegriffe , die notwendig sind, um im Kontext des Objektmodells zu verstehen.

Kontext: Der this-Zeiger

Da eine bestimmte Eigenschaft oder Methode auf jeder Ebene der Datenmodellstruktur implementiert werden kann, ist es erforderlich, dass die Implementierung der -Methode oder -Eigenschaft auf das ursprüngliche Objekt zugreifen kann (was Sie diesen Zeiger in C++ oder dieses Objekt in JavaScript nennen können. Dieser instance Objekt wird an eine Vielzahl von Methoden als erstes Argument als Kontext in den beschriebenen Methoden übergeben.

Kontext: Der Adressraum

Es ist wichtig zu beachten, dass Datenmodellschnittstellen diesen Kontext im Gegensatz zu früheren Erweiterungsmodellen, bei denen kontext (Ziel, Prozess, Thread, den Sie betrachten) ein UI-Konzept mit allen APIs im Verhältnis zum aktuellen UI-Zustand ist, diesen Kontext in der Regel explizit oder implizit als IDebugHostContext-Schnittstelle verwenden. Jedes IModelObject innerhalb des Datenmodells enthält diese Art von Kontextinformationen und kann diesen Kontext an zurückgegebene Objekte weitergeben. Dies bedeutet, dass beim Lesen eines systemeigenen Werts oder eines Schlüsselwerts aus einem IModelObject das Ziel und der Prozess ausgelesen werden, von denen das Objekt ursprünglich abgerufen wurde.

Es gibt einen expliziten konstanten Wert , USE_CURRENT_HOST_CONTEXT, der an Methoden übergeben werden kann, die ein IDebugHostContext-Argument verwenden. Dieser Wert gibt an, dass der Kontext tatsächlich dem aktuellen Ui-Zustand des Debuggers entspricht. Dieser Begriff muss jedoch explizit sein.

Kontext: Implementierung privater Daten

Denken Sie daran, dass jedes Objekt im Datenmodell tatsächlich ein Aggregat des Objekts instance und der Struktur der angefügten übergeordneten Modelle ist. Jedes dieser übergeordneten Modelle (die in den Ketten vieler verschiedener Objekte verknüpft werden können) kann privaten Implementierungsdaten jedem instance -Objekt zuordnen. Jedes IModelObject, das konzeptionell erstellt wird, verfügt über eine Hashtabelle, die ein bestimmtes übergeordnetes Modell privaten instance Daten zuordnet, die von einer IUnknown-Schnittstelle definiert werden. Dadurch kann ein übergeordnetes Modell Informationen zu jedem instance zwischenspeichern oder auf andere Weise beliebige Daten zugeordnet sein.

Auf diesen Kontexttyp kann über die Methoden GetContextForDataModel und SetContextForDataModel auf IModelObject zugegriffen werden.

Die Hauptdebuggerobjektschnittstelle: IModelObject


Die IModelObject-Schnittstelle ist wie folgt definiert:

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;
}

Grundlegende Methoden

Im Folgenden finden Sie allgemeine Methoden, die für jede Art von Objekt gelten, die durch ein IModelObject dargestellt wird.

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;

GetKind

Die GetKind-Methode gibt zurück, welche Art von Objekt im IModelObject-Objekt enthalten ist.

Getcontext

Die GetContext-Methode gibt den Hostkontext zurück, der dem -Objekt zugeordnet ist.

GetIntrinsicValue

Die GetIntrinsicValue-Methode gibt die Sache zurück, die in einem IModelObject-Objekt geschachtelt ist. Diese Methode darf nur auf IModelObject-Schnittstellen aufgerufen werden, die eine geschachtelte intrinsische oder eine bestimmte Schnittstelle darstellen, die geschachtelt ist. Es kann nicht für native Objekte, keine Wertobjekte, synthetischen Objekte und Verweisobjekte aufgerufen werden. Die GetIntrinsicValueAs-Methode verhält sich ähnlich wie die GetIntrinsicValue-Methode, mit der Ausnahme, dass sie den Wert in den angegebenen Variantentyp konvertiert. Wenn die Konvertierung nicht ausgeführt werden kann, gibt die Methode einen Fehler zurück.

IsEqualTo

Die IsEqualTo-Methode vergleicht zwei Modellobjekte und gibt zurück, ob sie gleich sind. Für Ein Objekt, das eine Reihenfolge aufweist, entspricht diese Methode, die true zurückgibt, der Compare-Methode, die 0 zurückgibt. Bei Objekten, die keine Reihenfolge aufweisen, aber gleichstellbar sind, schlägt die Compare-Methode fehl, dies ist jedoch nicht der Fall. Die Bedeutung eines wertbasierten Vergleichs wird durch den Typ des Objekts definiert. Derzeit ist dies nur für systeminterne Typen und Fehlerobjekte definiert. Es gibt kein aktuelles Datenmodellkonzept für die Gleichsetzung.

Dereference

Die Dereference-Methode dereferenziert ein -Objekt. Diese Methode kann verwendet werden, um einen datenmodellbasierten Verweis (ObjectTargetObjectReference, ObjectKeyReference) oder einen nativen Sprachverweis (einen Zeiger oder einen Sprachverweis) zu dereferenzieren. Es ist wichtig zu beachten, dass diese Methode eine einzelne Ebene der Verweissemantik für das -Objekt entfernt. Es ist für instance durchaus möglich, einen Datenmodellverweis auf einen Sprachverweis zu haben. In einem solchen Fall würde das erstmalige Aufrufen der Dereference-Methode den Datenmodellverweis entfernen und den Sprachverweis belassen. Das Aufrufen von Dereferenzierung für dieses resultierende Objekt würde anschließend den Sprachverweis entfernen und den nativen Wert unter diesem Verweis zurückgeben.

Schlüsselbearbeitungsmethoden

Jedes synthetische Objekt, das ein Wörterbuch von Schlüssel-, Wert- und Metadatentupeln ist, verfügt über eine Reihe von Methoden zum Bearbeiten dieser Schlüssel, Werte und der ihnen zugeordneten Metadaten.

Die wertbasierten Formen der APIs sind:

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;

Die referenzbasierten Formen der APIs sind:

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;

GetKeyValue

Die GetKeyValue-Methode ist die erste Methode, die ein Client verwendet, um den Wert (und die Metadaten, die einem bestimmten Schlüssel anhand des Namens zugeordnet sind) abzurufen. Wenn es sich bei dem Schlüssel um einen Eigenschaftsaccessor handelt, d. h. um einen Wert als IModelObject, bei dem es sich um einen IModelPropertyAccessor handelt, ruft die GetKeyValue-Methode des Eigenschaftszugriffsgebers automatisch auf, um den tatsächlichen Wert abzurufen.

SetKeyValue

Die SetKeyValue-Methode ist die erste Methode, die ein Client verwendet, um den Wert eines Schlüssels festzulegen. Diese Methode kann nicht verwendet werden, um einen neuen Schlüssel für ein -Objekt zu erstellen. Es wird nur der Wert eines vorhandenen Schlüssels festgelegt. Beachten Sie, dass viele Schlüssel schreibgeschützt sind (z. B. werden sie von einem Eigenschaftsaccessor implementiert, der E_NOT_IMPL aus der SetValue-Methode zurückgibt). Diese Methode schlägt fehl, wenn sie für einen schreibgeschützten Schlüssel aufgerufen wird.

EnumerateKeyValues

Die EnumerateKeyValues-Methode ist die erste Methode, die ein Client verwendet, um alle Schlüssel eines Objekts aufzulisten (dies schließt alle Schlüssel ein, die an einer beliebigen Stelle in der Struktur übergeordneter Modelle implementiert sind). Es ist wichtig zu beachten, dass EnumerateKeyValues alle Schlüssel aufzählt, die durch doppelte Namen in der Objektstruktur definiert sind. Methoden wie GetKeyValue und SetKeyValue bearbeiten jedoch nur die erste instance eines Schlüssels mit dem angegebenen Namen, wie er vom Tiefen-First-Traversal ermittelt wurde.

GetKey

Die GetKey-Methode ruft den Wert (und die metadaten zugeordneten) eines bestimmten Schlüssels anhand des Namens ab. Die meisten Clients sollten stattdessen die GetKeyValue-Methode verwenden. Wenn der Schlüssel ein Eigenschaftsaccessor ist, gibt der Aufruf dieser Methode den Eigenschaftsaccessor (eine IModelPropertyAccessor-Schnittstelle) zurück, die in einem IModelObject-Objekt geschachtelt ist. Im Gegensatz zu GetKeyValue löst diese Methode den zugrunde liegenden Wert des Schlüssels nicht automatisch auf, indem die GetValue-Methode aufgerufen wird. Diese Verantwortung ist die des Anrufers.

Setkey

Die SetKey-Methode ist die Methode, die ein Client verwendet, um einen Schlüssel für ein Objekt zu erstellen (und dem erstellten Schlüssel möglicherweise Metadaten zuzuordnen). Wenn ein angegebenes Objekt bereits über einen Schlüssel mit dem angegebenen Namen verfügt, tritt eines von zwei Verhaltensweisen auf. Wenn sich der Schlüssel auf dem instance befindet, der dadurch angegeben wird, wird der Wert dieses Schlüssels ersetzt, als ob der ursprüngliche Schlüssel nicht vorhanden wäre. Befindet sich der Schlüssel hingegen in der Kette der übergeordneten Datenmodelle der instance, die durch diesen angegeben wird, wird auf der instance, die durch diesen angegeben wird, ein neuer Schlüssel mit dem angegebenen Namen erstellt. Dies würde in der Tat dazu führen, dass das Objekt zwei Schlüssel mit demselben Namen aufweist (ähnlich wie eine abgeleitete Klasse, die einen Member mit demselben Namen wie eine Basisklasse überschatten würde).

EnumerateKeys

Die EnumerateKeys-Methode verhält sich ähnlich wie die EnumerateKeyValues-Methode, mit der Ausnahme, dass eigenschaftenaccessoren für das Objekt nicht automatisch aufgelöst werden. Wenn der Wert eines Schlüssels ein Eigenschaftsaccessor ist, gibt die EnumerateKeys-Methode den Eigenschaftsaccessor (eine IModelPropertyAccessorInterface) zurück, die in einem IModelObject geschachtelt ist, anstatt automatisch die GetValue-Methode aufzurufen. Dies ähnelt dem Unterschied zwischen GetKey und GetKeyValue.

ClearKeys

Die ClearKeys-Methode entfernt alle Schlüssel und die zugehörigen Werte und Metadaten aus der instance des durch diesen angegebenen Objekts. Diese Methode hat keine Auswirkungen auf übergeordnete Modelle, die an das jeweilige Objekt instance angefügt sind.

GetKeyReference

Die GetKeyReference-Methode sucht nach einem Schlüssel des angegebenen Namens im Objekt (oder seiner übergeordneten Modellkette) und gibt einen Verweis auf diesen Schlüssel zurück, der von einer IModelKeyReference-Schnittstelle angegeben wird, die in einem IModelObject-Objekt eingeschlossen ist. Dieser Verweis kann anschließend verwendet werden, um den Wert des Schlüssels abzurufen oder festzulegen.

EnumerateKeyReferences

Die EnumerateKeyReferences-Methode verhält sich ähnlich wie die EnumerateKeyValues-Methode, mit der Ausnahme, dass sie Verweise auf die Schlüssel zurückgibt, die sie aufzählt (angegeben durch eine IModelKeyReference-Schnittstelle, die in ein IModelObject-Objekt geschachtelt ist) anstelle des Werts des Schlüssels. Solche Verweise können verwendet werden, um den zugrunde liegenden Wert der Schlüssel abzurufen oder festzulegen.

Methoden zur Konzeptbearbeitung

Neben einem Modellobjekt, das ein Wörterbuch von Schlüssel-Wert-/Metadatentupeln ist, ist es auch ein Container mit Konzepten. Ein Konzept ist etwas Abstraktes, das für oder von einem Objekt ausgeführt werden kann. Konzepte sind im Wesentlichen ein dynamischer Speicher von Schnittstellen, den ein Objekt unterstützt. Das Datenmodell definiert heute eine Reihe von Konzepten:

Konzeptschnittstelle Beschreibung
IDataModelConcept Das Konzept ist ein übergeordnetes Modell. Wenn dieses Modell automatisch über eine registrierte Typsignatur an einen nativen Typ angefügt wird, wird die InitializeObject-Methode automatisch aufgerufen, wenn ein neues Objekt dieses Typs instanziiert wird.
IStringDisplayableConcept Das Objekt kann zu Anzeigezwecken in eine Zeichenfolge konvertiert werden.
IIterableConcept Das Objekt ist ein Container und kann durchlaufen werden.
IIndexableConcept Das Objekt ist ein Container und kann in einer oder mehreren Dimensionen indiziert werden (zugriff über zufälligen Zugriff).
IPreferredRuntimeTypeConcept Das Objekt versteht mehr über typen, die von ihm abgeleitet werden, als das zugrunde liegende Typsystem bereitstellen kann, und möchte seine eigenen Konvertierungen vom statischen in den Laufzeittyp verarbeiten.
IDynamicKeyProviderConcept Das Objekt ist ein dynamischer Schlüsselanbieter und möchte alle Schlüsselabfragen aus dem Kerndatenmodell übernehmen. Diese Schnittstelle wird in der Regel als Brücke zu dynamischen Sprachen wie JavaScript verwendet.
IDynamicConceptProviderConcept Das Objekt ist ein dynamischer Anbieter von Konzepten und möchte alle Konzeptabfragen aus dem Kerndatenmodell übernehmen. Diese Schnittstelle wird in der Regel als Brücke zu dynamischen Sprachen wie JavaScript verwendet.

Die folgenden Methoden für IModelObject werden verwendet, um die Von einem Objekt unterstützten Konzepte zu bearbeiten.

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;

GetConcept

Die GetConcept-Methode sucht nach einem Konzept für das Objekt (oder seine übergeordnete Modellkette) und gibt einen Schnittstellenzeiger auf die Konzeptschnittstelle zurück. Das Verhalten und die Methoden auf einer Konzeptschnittstelle sind für jedes Konzept spezifisch. Es ist jedoch wichtig zu beachten, dass viele der Konzeptschnittstellen erfordern, dass der Aufrufer explizit das Kontextobjekt (oder das, was man normalerweise diesen Zeiger nennen könnte) übergeben muss. Es ist wichtig sicherzustellen, dass das richtige Kontextobjekt an jede Konzeptschnittstelle übergeben wird.

SetConcept

Die SetConcept-Methode platziert ein angegebenes Konzept für das Objekt instance, das durch diesen Zeiger angegeben wird. Wenn ein übergeordnetes Modell, das an das Objekt angefügt instance, das dadurch angegeben wird, auch das Konzept unterstützt, überschreibt die Implementierung im instance dies im übergeordneten Modell.

ClearConcepts

Die ClearConcepts-Methode entfernt alle Konzepte aus der instance des durch diesen angegebenen Objekt.

Native Objektmethoden

Während viele Modellobjekte auf systeminterne (z. B. ganze Zahlen, Zeichenfolgen) oder synthetische Konstrukte (ein Wörterbuch von Schlüssel-Wert-/Metadatentupeln und -konzepten) verweisen, kann ein Modellobjekt auch auf ein natives Konstrukt (z. B. einen benutzerdefinierten Typ im Adressraum des Debugziels) verweisen. Die IModelObject-Schnittstelle verfügt über eine Reihe von Methoden, die auf Informationen zu solchen nativen Objekten zugreifen. Diese Methoden sind:

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;

GetRawValue

Die GetRawValue-Methode findet ein natives Konstrukt innerhalb des angegebenen Objekts. Ein solches Konstrukt kann ein Feld, eine Basisklasse, ein Feld in einer Basisklasse, eine Memberfunktion usw. sein...

EnumerateRawValues

Die EnumerateRawValues-Methode listet alle nativen untergeordneten Elemente (z. B. Felder, Basisklassen usw.) des angegebenen Objekts auf.

TryCastToRuntimeType

Die TryCastToRuntimeType-Methode fordert den Debughost auf, eine Analyse durchzuführen und den tatsächlichen Laufzeittyp (z. B. die am meisten abgeleitete Klasse) des angegebenen Objekts zu bestimmen. Die genaue Analyse ist spezifisch für den Debughost und kann RTTI (C++-Laufzeittypinformationen), die Untersuchung der V-Table-Struktur (virtuelle Funktionstabelle) des Objekts oder andere Mittel enthalten, mit denen der Host den dynamischen/Laufzeittyp zuverlässig anhand des statischen Typs bestimmen kann. Fehler bei der Konvertierung in einen Laufzeittyp bedeutet nicht, dass dieser Methodenaufruf fehlschlägt. In solchen Fällen gibt die -Methode das angegebene Objekt (diesen Zeiger) im Ausgabeargument zurück.

Getlocation

Die GetLocation-Methode gibt den Speicherort des nativen Objekts zurück. Ein solcher Speicherort ist zwar in der Regel eine virtuelle Adresse innerhalb des Adressraums des Debugziels, dies ist jedoch nicht unbedingt der Fall. Der von dieser Methode zurückgegebene Speicherort ist ein abstrakter Speicherort, der eine virtuelle Adresse sein kann, die Platzierung innerhalb eines Registers oder Unterregisters oder einen anderen beliebigen Adressraum angeben kann, wie vom Debughost definiert. Wenn das Feld HostDefined des resultierenden Location-Objekts 0 ist, gibt dies an, dass der Speicherort tatsächlich eine virtuelle Adresse ist. Eine solche virtuelle Adresse kann durch Untersuchung des Felds Offset des resultierenden Standorts abgerufen werden. Jeder Wert ungleich 0 des Felds HostDefined gibt einen alternativen Adressraum an, wobei das Offset-Feld der Offset innerhalb dieses Adressraums ist. Die genaue Bedeutung von HostDefined-Werten ungleich Null ist für den Debughost privat.

GetTypeInfo

Die GetTypeInfo-Methode gibt den systemeigenen Typ des angegebenen Objekts zurück. Wenn dem Objekt keine systemeigenen Typinformationen zugeordnet sind (z. B. ist es intrinsisch, usw.) ist der Aufruf weiterhin erfolgreich, gibt aber NULL zurück.

GetTargetInfo

Die GetTargetInfo-Methode ist im Grunde eine Kombination der GetLocation- und GetTypeInfo-Methoden, die sowohl den abstrakten Speicherort als auch den nativen Typ des angegebenen Objekts zurückgeben.

GetRawReference

Die GetRawReference-Methode sucht ein natives Konstrukt innerhalb des angegebenen Objekts und gibt einen Verweis darauf zurück. Ein solches Konstrukt kann ein Feld, eine Basisklasse, ein Feld in einer Basisklasse, eine Memberfunktion usw. sein... Es ist wichtig, den hier zurückgegebenen Verweis (ein Objekt vom Typ ObjectTargetObjectReference) von einem Sprachverweis (z. B. einen C++-& oder && Stilverweis) zu unterscheiden.

EnumerateRawReferences

Die EnumerateRawReferences-Methode listet Verweise auf alle nativen untergeordneten Elemente (z. B. Felder, Basisklassen usw.) des angegebenen Objekts auf.

Erweiterbarkeitsmethoden

Wie bereits beschrieben, verhält sich ein Modellobjekt einem JavaScript-Objekt und seiner Prototypkette sehr ähnlich. Zusätzlich zu den instance, die durch eine bestimmte IModelObject-Schnittstelle dargestellt werden, kann eine beliebige Anzahl von übergeordneten Modellen an das Objekt angefügt sein (von denen wiederum eine beliebige Anzahl übergeordneter Modelle angefügt ist). Dies ist das primäre Mittel für die Erweiterbarkeit innerhalb des Datenmodells. Wenn eine bestimmte Eigenschaft oder ein bestimmtes Konzept nicht innerhalb einer bestimmten instance gefunden werden kann, wird eine Tiefensuche der Objektstruktur (definiert durch übergeordnete Modelle) durchgeführt, die am instance basiert.

Die folgenden Methoden bearbeiten die Kette von übergeordneten Modellen, die einem bestimmten IModelObject-instance zugeordnet sind:

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;

GetNumberOfParentModels

Die GetNumberOfParentModels-Methode gibt die Anzahl der übergeordneten Modelle zurück, die an das angegebene Objekt instance angefügt sind. Übergeordnete Modelle werden in der linearen Reihenfolge der übergeordneten Modellkette zuerst nach Eigenschaften gesucht.

GetParentModel

Die GetParentModel-Methode gibt das übergeordnete Modell in der übergeordneten Modellkette des angegebenen Objekts zurück. Übergeordnete Modelle werden nach einer Eigenschaft oder einem Konzept in der linearen Reihenfolge gesucht, in der sie hinzugefügt oder aufgezählt werden. Das übergeordnete Modell mit index i von null wird (hierarchisch) vor dem übergeordneten Modell mit index i + 1 durchsucht.

AddParentModel

Die AddParentModel-Methode fügt dem angegebenen Objekt ein neues übergeordnetes Modell hinzu. Ein solches Modell kann am Ende der Suchkette (das Override-Argument wird als false angegeben) oder am Anfang der Suchkette (das Override-Argument wird als true angegeben) hinzugefügt werden. Darüber hinaus kann jedes übergeordnete Modell optional den Kontext (die Semantik dieses Zeigers) für jede Eigenschaft oder jedes Konzept auf dem angegebenen übergeordneten Element (oder einer beliebigen Person in seiner übergeordneten Hierarchie) anpassen. Kontextanpassung wird selten verwendet, ermöglicht aber einige leistungsstarke Konzepte wie das Einbetten von Objekten, das Erstellen von Namespaces usw.

RemoveParentModel

RemoveParentModel entfernt ein angegebenes übergeordnetes Modell aus der übergeordneten Suchkette des angegebenen Objekts.

SetContextForDataModel

Die SetContextForDataModel-Methode wird von der Implementierung eines Datenmodells verwendet, um Implementierungsdaten auf instance-Objekten zu platzieren. Konzeptionell enthält jedes IModelObject (der Einfachheit halber die instance nennen) eine Hashtabelle mit dem Zustand. Die Hashtabelle wird von einem anderen IModelObject indiziert (nennen Sie dies der Einfachheit halber das Datenmodell), das sich in der übergeordneten Modellhierarchie des instance befindet. Der in diesem Hash enthaltene Wert ist ein Satz von Verweiszählungsstatusinformationen, die durch eine IUnknown-instance dargestellt werden. Sobald das Datenmodell diesen Zustand auf dem instance festgelegt hat, kann es beliebige Implementierungsdaten speichern, die z. B. bei Eigenschaften gettern abgerufen werden können.

GetContextForDataModel

Die GetContextForDataModel-Methode wird verwendet, um Kontextinformationen abzurufen, die mit einem vorherigen Aufruf von SetContextForDataModel eingerichtet wurden. Dadurch werden Zustandsinformationen abgerufen, die für ein instance-Objekt von einem Datenmodell weiter oben in der übergeordneten Modellhierarchie des instance-Objekts festgelegt wurden. Weitere Details zu diesem Kontext/Zustand und seiner Bedeutung finden Sie in der Dokumentation zu SetContextForDataModel.

Debuggerdatenmodell-Kernobjekttypen

Ein Objekt im Datenmodell ähnelt dem Konzept von Object in .NET. Es ist der generische Container, in den das Konstrukt, das das Datenmodell versteht, eingeschlossen werden kann. Neben nativen Objekten und synthetischen (dynamischen) Objekten gibt es eine Reihe von Kernobjekttypen, die im Container eines IModelObject platziert (oder geboxt werden können). Der Container, in dem die meisten dieser Werte platziert werden, ist ein COM/OLE VARIANT-Standard mit einer Reihe von zusätzlichen Einschränkungen, die darauf festgelegt sind, was dieser VARIANT enthalten kann. Die einfachsten Typen sind:

  • 8-Bit-Werte ohne Vorzeichen und Vorzeichen (VT_UI1, VT_I1)
  • 16-Bit-Werte ohne Vorzeichen und Vorzeichen (VT_UI2, VT_UI2)
  • 32-Bit-Werte ohne Vorzeichen und Vorzeichen (VT_UI4, VT_I4)
  • 64-Bit-Werte ohne Vorzeichen und Vorzeichen (VT_UI8, VT_I8)
  • Gleitkommawerte mit einfacher und doppelter Genauigkeit (VT_R4, VT_R8)
  • Zeichenfolgen (VT_BSTR)
  • Boolesche (VT_BOOL)

Zusätzlich zu diesen grundlegenden Typen werden eine Reihe von kernen Datenmodellobjekten in IModelObject platziert, das von VT_UNKNOWN definiert wird, wobei die gespeicherte IUnknown garantiert eine bestimmte Schnittstelle implementiert. Diese Typen lauten:

  • Eigenschaftsaccessoren (IModelPropertyAccessor)
  • Methodenobjekte (IModelMethod)
  • Schlüsselreferenzobjekte (IModelKeyReference oder IModelKeyReference2)
  • Kontextobjekte (IDebugModelHostContext)

Eigenschaftsaccessoren: IModelPropertyAccessor

Ein Eigenschaftenzugriffsor im Datenmodell ist eine Implementierung der IModelPropertyAccessor-Schnittstelle, die in einem IModelObject-Objekt enthalten ist. Das Modellobjekt gibt eine Art ObjectPropertyAccessor zurück, wenn es abgefragt wird, und der systeminterne Wert ist ein VT_UNKNOWN der garantiert für IModelPropertyAccessor abgefragt werden kann. Im Prozess ist es garantiert, dass es statisch in IModelPropertyAccessor umgewandelt werden kann.

Ein Eigenschaftszugriffsor ist eine indirekte Möglichkeit, einen Methodenaufruf zum Abrufen und Festlegen eines Schlüsselwerts im Datenmodell abzurufen. Wenn der Wert eines bestimmten Schlüssels ein Eigenschaftszugriffsor ist, wird dies von den Methoden GetKeyValue und SetKeyValue automatisch bemerkt und die dem Eigenschaftenzugriff zugrunde liegenden GetValue- oder SetValue-Methoden nach Bedarf aufgerufen.

Die IModelPropertyAccessor-Schnittstelle ist wie folgt definiert:

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; 
}

Getvalue

Die GetValue-Methode ist der Getter für den Eigenschaftenzugriffsor. Er wird immer dann aufgerufen, wenn ein Client den zugrunde liegenden Wert der Eigenschaft abrufen möchte. Beachten Sie, dass jeder Aufrufer, der direkt einen Eigenschaftszugriffsor abruft, dafür verantwortlich ist, den Schlüsselnamen und die genaue instance -Objekts (dieser Zeiger) an die GetValue-Methode des Eigenschaftszugriffers zu übergeben.

SetValue

Die SetValue-Methode ist der Setter für den Eigenschaftenzugriffsor. Er wird immer dann aufgerufen, wenn ein Client der zugrunde liegenden Eigenschaft einen Wert zuweisen möchte. Viele Eigenschaften sind schreibgeschützt. In solchen Fällen gibt das Aufrufen der SetValue-Methode E_NOTIMPL zurück. Beachten Sie, dass jeder Aufrufer, der direkt einen Eigenschaftszugriffsor abruft, für die Übergabe des Schlüsselnamens und der genauen instance -Objekts (dieser Zeiger) an die SetValue-Methode des Eigenschaftenzugriffers verantwortlich ist.

Methoden: IModelMethod

Eine Methode im Datenmodell ist eine Implementierung der IModelMethod-Schnittstelle, die in einem IModelObject-Objekt enthalten ist. Das Modellobjekt gibt eine Art ObjectMethod zurück, wenn es abgefragt wird, und der systeminterne Wert ist ein VT_UNKNOWN der garantiert für IModelMethod befragbar ist. Im Prozess ist es garantiert, dass es statisch in IModelMethod umgewandelt werden kann. Alle Methoden im Datenmodell sind dynamischer Natur. Sie verwenden als Eingabe einen Satz von 0 oder mehr Argumenten und geben einen einzelnen Ausgabewert zurück. Es gibt keine Überladungsauflösung und keine Metadaten zu Parameternamen, Typen oder Erwartungen.

Die IModelMethod-Schnittstelle ist wie folgt definiert:

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;
}

Call

Die Call-Methode ist die Art und Weise, wie jede im Datenmodell definierte Methode aufgerufen wird. Der Aufrufer ist dafür verantwortlich, ein genaues instance -Objekt (dieser Zeiger) und einen beliebigen Satz von Argumenten zu übergeben. Das Ergebnis der Methode und alle optionalen Metadaten, die diesem Ergebnis zugeordnet sind, werden zurückgegeben. Methoden, die einen Wert nicht logisch zurückgeben, müssen trotzdem ein gültiges IModelObject zurückgeben. In einem solchen Fall ist das IModelObject ein boxed no value. Falls eine Methode fehlschlägt, kann sie optional erweiterte Fehlerinformationen im Eingabeargument zurückgeben (auch wenn das zurückgegebene HRESULT ein Fehler ist). Es ist unbedingt erforderlich, dass Anrufer dies überprüfen.

Schlüsselverweise: IModelKeyReference oder IModelKeyReference2

Ein Schlüsselverweis ist im Wesentlichen ein Handle für einen Schlüssel für ein bestimmtes Objekt. Ein Client kann ein solches Handle über Methoden wie GetKeyReference abrufen und das Handle später verwenden, um den Wert des Schlüssels abzurufen oder festzulegen, ohne unbedingt das ursprüngliche Objekt zu halten. Bei diesem Objekttyp handelt es sich um eine Implementierung der IModelKeyReference- oder IModelKeyReference2-Schnittstelle, die in einem IModelObject-Objekt enthalten ist. Das Modellobjekt gibt eine Art ObjectKeyReference zurück, wenn es abgefragt wird, und der systeminterne Wert ist ein VT_UNKNOWN der garantiert für IModelKeyReference abfragbar ist. Bei der Bearbeitung wird garantiert, dass sie statisch in IModelKeyReference umgewandelt werden kann.

Die Schlüsselreferenzschnittstelle ist wie folgt definiert:

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;
}

GetKeyName

Die GetKeyName-Methode gibt den Namen des Schlüssels zurück, auf den dieser Schlüsselverweis ein Handle ist. Die zurückgegebene Zeichenfolge ist ein Standard-BSTR und muss über einen Aufruf von SysFreeString freigegeben werden.

GetOriginalObject

Die GetOriginalObject-Methode gibt das instance-Objekt zurück, aus dem der Schlüsselverweis erstellt wurde. Beachten Sie, dass sich der Schlüssel selbst in einem übergeordneten Modell des instance-Objekts befinden kann.

GetContextObject

Die GetContextObject-Methode gibt den Kontext (diesen Zeiger) zurück, der an die GetValue- oder SetValue-Methode eines Eigenschaftszugriffsgebers übergeben wird, wenn der betreffende Schlüssel auf einen Eigenschaftenzugriffsor verweist. Das hier zurückgegebene Kontextobjekt kann mit dem ursprünglichen Objekt identisch sein, das von GetOriginalObject abgerufen wurde. Wenn sich ein Schlüssel in einem übergeordneten Modell befindet und diesem übergeordneten Modell ein Kontextanpassungsor zugeordnet ist, ist das ursprüngliche Objekt das instance-Objekt, für das GetKeyReference oder EnumerateKeyReferences aufgerufen wurde. Das Kontextobjekt ist das, was aus der endgültigen Kontextanpassung zwischen dem ursprünglichen Objekt und dem übergeordneten Modell mit dem Schlüssel stammt, auf den dieser Schlüsselverweis ein Handle ist. Wenn keine Kontextanpassungen vorhanden sind, sind das ursprüngliche Objekt und das Kontextobjekt identisch.

GetKey

Die GetKey-Methode für einen Schlüsselverweis verhält sich wie die GetKey-Methode auf IModelObject. Es gibt den Wert des zugrunde liegenden Schlüssels und alle dem Schlüssel zugeordneten Metadaten zurück. Wenn der Wert des Schlüssels ein Eigenschaftszugriffsor ist, gibt dies den Eigenschaftszugriffsor (IModelPropertyAccessor) zurück, der in ein IModelObject eingeboxt ist. Diese Methode ruft die zugrunde liegende GetValue- oder SetValue-Methode für den Eigenschaftenzugriffsor nicht auf.

GetKeyValue

Die GetKeyValue-Methode für einen Schlüsselverweis verhält sich wie die GetKeyValue-Methode auf IModelObject. Es gibt den Wert des zugrunde liegenden Schlüssels und alle dem Schlüssel zugeordneten Metadaten zurück. Wenn der Wert des Schlüssels ein Eigenschaftszugriffsor ist, wird automatisch die zugrunde liegende GetValue-Methode für den Eigenschaftenzugriffsor aufgerufen.

Setkey

Die SetKey-Methode für einen Schlüsselverweis verhält sich wie die SetKey-Methode auf IModelObject. Er weist den Wert des Schlüssels zu. Wenn der ursprüngliche Schlüssel ein Eigenschaftszugriffsor war, ersetzt dies den Eigenschaftenzugriffsor. Die SetValue-Methode wird nicht für den Eigenschaftenzugriffsor aufgerufen.

SetKeyValue

Die SetKeyValue-Methode für einen Schlüsselverweis verhält sich wie die SetKeyValue-Methode auf IModelObject. Er weist den Wert des Schlüssels zu. Wenn der ursprüngliche Schlüssel ein Eigenschaftsaccessor war, wird dadurch die zugrunde liegende SetValue-Methode für den Eigenschaftenaccessor aufgerufen, anstatt den Eigenschaftenaccessor selbst zu ersetzen.

OverrideContextObject

Die OverrideContextObject-Methode (nur in IModelKeyReference2 vorhanden) ist eine erweiterte Methode, die verwendet wird, um das Kontextobjekt dauerhaft zu ändern, das dieser Schlüsselverweis an die GetValue- oder SetValue-Methoden des zugrunde liegenden Eigenschaftenzugriffsgebers übergeben wird. Das an diese Methode übergebene Objekt wird auch von einem Aufruf von GetContextObject zurückgegeben. Diese Methode kann von Skriptanbietern verwendet werden, um bestimmte dynamische Sprachverhalten zu replizieren. Die meisten Clients sollten diese Methode nicht aufrufen.

Context-Objekte: IDebugHostContext

Kontextobjekte sind undurchsichtige Informationsblobs, die der Debughost (in Zusammenarbeit mit dem Datenmodell) jedem Objekt zuordnet. Es kann Dinge wie den Prozesskontext oder den Adressraum enthalten, aus dem die Informationen stammen, usw. Ein Kontextobjekt ist eine Implementierung von IDebugHostContext, die in einem IModelObject geschachtelt ist. Beachten Sie, dass IDebugHostContext eine vom Host definierte Schnittstelle ist. Ein Client implementiert diese Schnittstelle niemals.

Weitere Informationen zu Kontextobjekten finden Sie unter Debuggerdatenmodell-C++-Hostschnittstellen in Debuggerdatenmodell-C++-Schnittstellen.

Der Datenmodell-Manager

Die Kernschnittstelle zum Datenmodell-Manager, IDataModelManager2 (oder dem früheren IDataModelManager), wird wie folgt definiert:

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;
}

Verwaltungsmethoden

Die folgenden Methoden werden von der Anwendung (z. B. debugger) verwendet, die das Datenmodell hostet.

STDMETHOD(Close)() PURE;

Schließen

Die Close-Methode wird im Datenmodell-Manager von einer Anwendung (z. B. debugger) aufgerufen, die das Datenmodell hostt, um den Herunterfahrensprozess des Datenmodell-Managers zu starten. Ein Host des Datenmodells, der die Close-Methode vor der Veröffentlichung seiner endgültigen Referenz auf den Datenmodell-Manager nicht verwendet, kann zu undefiniertem Verhalten führen, einschließlich, aber nicht beschränkt auf erhebliche Lecks der Verwaltungsinfrastruktur für das Datenmodell.

Objekterstellung/Boxingmethoden

Der folgende Satz von Methoden wird verwendet, um neue Objekte zu erstellen oder Werte in ein IModelObject -- die Kernschnittstelle des Datenmodells - zu boxen.

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;

CreateNoValue

Die CreateNoValue-Methode erstellt ein "no value"-Objekt, boxt es in ein IModelObject und gibt es zurück. Das zurückgegebene Modellobjekt verfügt über eine Art von ObjectNoValue.

Ein "no value"-Objekt hat mehrere semantische Bedeutungen:

  • (Abhängig von der Sprache) kann es als semantische Entsprechung von void, NULL oder undefiniert betrachtet werden.
  • Die GetValue-Methode eines Eigenschaftsaccessors, die erfolg und ein resultierendes "no value"-Objekt zurückgibt, gibt an, dass die bestimmte Eigenschaft keinen Wert für die angegebene instance hat und so behandelt werden sollte, als ob die Eigenschaft für diesen bestimmten instance nicht vorhanden wäre.
  • Datenmodellmethoden, die semantisch nicht über einen Rückgabewert verfügen, verwenden diesen als Sentinel, um dies anzugeben (da eine Methode ein gültiges IModelObject zurückgeben muss).

CreateErrorObject

Die CreateErrorObject-Methode erstellt ein "Error-Objekt". Das Datenmodell verfügt nicht über das Konzept von Ausnahmen und Ausnahmefluss. Fehler treten aus einer Eigenschaft/Methode auf zwei Arten auf:

  • Ein einzelnes fehlerhaftes HRESULT ohne erweiterte Fehlerinformationen. Entweder gibt es keine weiteren Informationen, die für den Fehler angegeben werden können, oder der Fehler selbst ist aus dem zurückgegebenen HRESULT selbsterklärend.
  • Ein einzelnes fehlerhaftes HRESULT,das mit erweiterten Fehlerinformationen gekoppelt ist. Die erweiterten Fehlerinformationen sind ein Fehlerobjekt, das im Ausgabeargument der Eigenschaft/Methode zurückgegeben wird.

CreateTypedObject

Die CreateTypedObject-Methode ist die Methode, mit der ein Client eine Darstellung eines nativen/Sprachobjekts im Adressraum eines Debugziels erstellen kann. Wenn der Typ des neu erstellten Objekts (wie durch das objectType-Argument angegeben) mit einer oder mehreren Typsignaturen übereinstimmt, die beim Datenmodell-Manager als kanonische Schnellansichten oder Erweiterungen registriert sind, werden diese übereinstimmenden Datenmodelle automatisch an das erstellte instance -Objekt angefügt, bevor es an den Aufrufer zurückgegeben wird.

CreateTypedObjectReference

Die CreateTypedObjectReference-Methode ähnelt semantisch der CreateTypedObject-Methode, mit der Ausnahme, dass sie einen Verweis auf das zugrunde liegende native/sprachbasierte Konstrukt erstellt. Der erstellte Verweis ist ein Objekt, das über eine Art ObjectTargetObjectReference verfügt. Es handelt sich nicht um einen nativen Verweis, da die zugrunde liegende Sprache möglicherweise unterstützt wird (z. B. ein C++-& oder &&). Es ist durchaus möglich, ein ObjectTargetObjectReference auf einen C++-Verweis zu verwenden. Ein Objekt der Art ObjectTargetObjectReference kann mithilfe der Dereference-Methode für IModelObject in den zugrunde liegenden Wert konvertiert werden. Der Verweis kann auch an die Ausdrucksauswertung des zugrunde liegenden Hosts übergeben werden, um dem Wert in einer sprachgerechten Weise wieder zuzuweisen.

CreateSyntheticObject

Die CreateSyntheticObject-Methode erstellt ein leeres Datenmodellobjekt – ein Wörterbuch mit Schlüssel-/Wert-/Metadatentupeln und -konzepten. Zum Zeitpunkt der Erstellung gibt es keine Schlüssel oder Konzepte für das Objekt. Es ist eine sauber Slate, die der Aufrufer verwenden kann.

CreateDataModelObject

Die CreateDataModelObject-Methode ist ein einfacher Hilfswrapper zum Erstellen von Objekten, die Datenmodelle sind, also Objekte, die als übergeordnete Modelle an andere Objekte angefügt werden. Alle diese Objekte müssen das Datenmodellkonzept über IDataModelConcept unterstützen. Diese Methode erstellt ein neues leeres synthetisches Objekt ohne expliziten Kontext und fügt das inpassierte IDataModelConcept als implementierung des neu erstellten Objekts des Datenmodellkonzepts hinzu. Dies kann auch durch Aufrufe von CreateSyntheticObject und SetConcept erreicht werden.

CreateIntrinsicObject

Die CreateIntrinsicObject-Methode ist die Methode, die systeminterne Werte in IModelObject eingibt. Der Aufrufer platziert den Wert in einem COM VARIANT-Element und ruft diese Methode auf. Der Datenmodell-Manager gibt ein IModelObject zurück, das das Objekt darstellt. Beachten Sie, dass diese Methode auch verwendet wird, um grundlegende IUnknown-basierte Typen einzuschachteln: Eigenschaftenaccessoren, Methoden, Kontexte usw. In solchen Fällen gibt die objectKind-Methode an, welche Art von IUnknown-basiertem Konstrukt das Objekt darstellt, und das PunkVal-Feld der übergebenen Variante ist der abgeleitete IUnknown-Typ. Der Typ muss statisch in die entsprechende Modellschnittstelle umgewandelt werden können (z. B. IModelPropertyAccessor, IModelMethod, IDebugHostContext usw.). Die variant-Typen, die von dieser Methode unterstützt werden, sind VT_UI1, VT_I1, VT_UI2, VT_I2, VT_UI4, VT_I4, VT_UI8, VT_I8, VT_R4, VT_R8, VT_BOOL, VT_BSTR und VT_UNKNOWN (für einen spezialisierten Satz von IUnknown abgeleiteten Typen, wie durch die ModelObjectKind-Enumeration angegeben.

CreateTypedIntrinsicObject

Die CreateTypedintrinsicObject-Methode ähnelt der CreateIntrinsicObject-Methode, mit der Ausnahme, dass mit ihr ein nativer/sprachiger Typ den Daten zugeordnet und zusammen mit dem boxed-Wert mitgeführt werden kann. Dadurch kann das Datenmodell Konstrukte wie native Enumerationstypen darstellen (die einfach VT_UI* oder VT_I*-Werte sind). Zeigertypen werden auch mit dieser Methode erstellt. Ein nativer Zeiger im Datenmodell ist eine erweiterte 64-Bit-Menge, die einen Offset in den virtuellen Adressraum des Debugziels darstellt. Es wird in einem VT_UI8 eingeschachtelt und mit dieser Methode und einem Typ erstellt, der einen nativen/sprachlichen Zeiger angibt.

CreateMetadataStore

Die CreateMetadataStore-Methode erstellt einen Schlüsselspeicher – einen vereinfachten Container aus Schlüssel-Wert-/Metadatentupeln – der zum Speichern von Metadaten verwendet wird, die Eigenschaften und einer Vielzahl anderer Werte zugeordnet werden können. Ein Metadatenspeicher kann über ein einzelnes übergeordnetes Element verfügen (das wiederum über ein einzelnes übergeordnetes Element verfügen kann). Wenn sich ein bestimmter Metadatenschlüssel nicht in einem bestimmten Speicher befindet, werden seine übergeordneten Elemente überprüft. Die meisten Metadatenspeicher verfügen nicht über übergeordnete Elemente. Es bietet jedoch eine Möglichkeit, allgemeine Metadaten einfach zu teilen.

CreateTypedIntrinsicObjectEx

Die CreateTypedIntrinsicObjectEx-Methode ähnelt semantisch der CreateTypedIntrinsicObject-Methode. Der einzige Unterschied zwischen den beiden besteht darin, dass diese Methode es dem Aufrufer ermöglicht, den Kontext anzugeben, in dem die systeminternen Daten gültig sind. Wenn kein Kontext übergeben wird, werden die Daten in jedem Kontext als gültig betrachtet, der vom Typargument geerbt wird (wie sich CreateTypedIntrinsicObject verhält). Dies ermöglicht die Erstellung von typisierten Zeigerwerten im Debugziel, die einen spezifischeren Kontext erfordern, als vom Typ geerbt werden kann.

Erweiterbarkeit/Registrierungsmethoden Die folgenden Methoden verwalten den Erweiterbarkeitsmechanismus des Datenmodells, sodass ein Client vorhandene Modelle erweitern oder registrieren oder das Datenmodell auffordern kann, automatisch ein bestimmtes übergeordnetes Modell an native Typen anzufügen, die einem bestimmten Kriterium entsprechen.

    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;

GetModelForTypeSignature

Die GetModelForTypeSignature-Methode gibt das Datenmodell zurück, das für eine bestimmte Typsignatur über einen vorherigen Aufruf der RegisterModelForTypeSignature-Methode registriert wurde. Das von dieser Methode zurückgegebene Datenmodell gilt als kanonische Schnellansicht für jeden Typ, der der übergebenen Typsignatur entspricht. Als kanonische Schnellansicht übernimmt dieses Datenmodell die Anzeige des Typs. Anzeige-Engines blenden standardmäßig native/sprachbasierte Konstrukte des Objekts zugunsten der Ansicht des Objekts aus, das vom Datenmodell dargestellt wird.

GetModelForType

Die GetModelForType-Methode gibt das Datenmodell zurück, das die kanonische Schnellansicht für einen bestimmten Typ instance. Tatsächlich findet diese Methode die am besten übereinstimmende Typsignatur, die mit einem vorherigen Aufruf der RegisterModelForTypeSignature-Methode registriert wurde, und gibt das zugeordnete Datenmodell zurück.

RegisterModelForTypeSignature

Die RegisterModelForTypeSignature-Methode ist die primäre Methode, die ein Aufrufer verwendet, um eine kanonische Schnellansicht für einen bestimmten Typ (oder satz von Typen) zu registrieren. Eine kanonische Schnellansicht ist ein Datenmodell, das die Anzeige eines bestimmten Typs (oder einer Gruppe von Typen) übernimmt. Anstelle der nativen/sprachlichen Ansicht des Typs, die in einer beliebigen Debugger-Benutzeroberfläche angezeigt wird, wird die Ansicht des Typs angezeigt, wie er vom registrierten Datenmodell dargestellt wird (zusammen mit einer Möglichkeit, die Native-/Sprachansicht für einen Benutzer, der dies wünscht, zurückzukehren).

UnregisterModelForTypeSignature

Die UnregisterModelForTypeSignature-Methode hebt einen vorherigen Aufruf der RegisterModelForTypeSignature-Methode auf. Diese Methode kann entweder ein bestimmtes Datenmodell als kanonische Schnellansicht für Typen entfernen, die einer bestimmten Typsignatur entsprechen, oder sie kann ein bestimmtes Datenmodell als kanonische Schnellansicht für jede Typsignatur entfernen, unter der dieses Datenmodell registriert ist.

RegisterExtensionForTypeSignature

Die RegisterExtensionForTypeSignature-Methode ähnelt der RegisterModelForTypeSignature-Methode mit einem wesentlichen Unterschied. Das datenmodell, das an diese Methode übergeben wird, ist nicht die kanonische Schnellansicht für jeden Typ und übernimmt nicht die Anzeige der nativen/sprachlichen Ansicht dieses Typs. Das Datenmodell, das an diese Methode übergeben wird, wird automatisch als übergeordnetes Element zu jedem konkreten Typ hinzugefügt, der der angegebenen Typsignatur entspricht. Im Gegensatz zur RegisterModelForTypeSignature-Methode gibt es keine Beschränkung für identische oder mehrdeutige Typsignaturen, die als Erweiterungen für einen bestimmten Typ (oder satz von Typen) registriert werden. Jede Erweiterung, deren Typsignatur einem bestimmten konkreten Typ instance entspricht, bewirkt, dass das über diese Methode registrierte Datenmodell automatisch als übergeordnete Modelle an neu erstellte Objekte angefügt wird. Dies ermöglicht es einer beliebigen Anzahl von Clients, einen Typ (oder satz von Typen) um neue Felder oder Funktionen zu erweitern.

Aufheben der RegistrierungExtensionForTypeSignature

Die UnregisterExtensionForTypeSignature-Methode hebt einen vorherigen Aufruf von RegisterExtensionForTypeSignature auf. Es hebt die Registrierung eines bestimmten Datenmodells als Erweiterung für eine bestimmte Typsignatur oder als Erweiterung für alle Typsignaturen auf, für die das Datenmodell registriert wurde.

GetRootNamespace

Die GetRootNamespace-Methode gibt den Stammnamespace des Datenmodells zurück. Dies ist ein Objekt, das vom Datenmodell verwaltet wird und in das der Debughost bestimmte Objekte platziert.

RegisterNamedModel

Die RegisterNamedModel-Methode registriert ein bestimmtes Datenmodell unter einem bekannten Namen, sodass es von Clients gefunden werden kann, die es erweitern möchten. Dies ist der Hauptzweck der API, um ein Datenmodell als etwas zu veröffentlichen, das erweitert werden kann, indem das unter diesem bekannten Namen registrierte Modell abgerufen und ein übergeordnetes Modell hinzugefügt wird.

UnregisterNamedModel

Die UnregisterNamedModel-Methode hebt einen vorherigen Aufruf von RegisterNamedModel zurück. Es entfernt die Zuordnung zwischen einem Datenmodell und einem Namen, unter dem es gesucht werden kann.

AcquireNamedModel

Ein Aufrufer, der ein Datenmodell erweitern möchte, das unter einem bestimmten Namen registriert ist, ruft die AcquireNamedModel-Methode auf, um das Objekt für das Datenmodell abzurufen, das er erweitern möchte. Diese Methode gibt das Datenmodell zurück, das über einen vorherigen Aufruf der RegisterNamedModel-Methode registriert wurde. Da der Hauptzweck der AcquireNamedModel-Methode darin besteht, das Modell zu erweitern, hat diese Methode ein besonderes Verhalten, wenn noch kein Modell unter dem angegebenen Namen registriert wurde. Wenn noch kein Modell unter dem angegebenen Namen registriert wurde, wird ein Stubobjekt erstellt, vorübergehend unter dem angegebenen Namen registriert und an den Aufrufer zurückgegeben. Wenn das reale Datenmodell über einen Aufruf der RegisterNamedModel-Methode registriert wird, werden alle Änderungen, die am Stubobjekt vorgenommen wurden, tatsächlich am realen Modell vorgenommen. Dadurch werden viele Abhängigkeitsprobleme der Ladereihenfolge von Komponenten beseitigt, die sich gegenseitig erweitern.

Hilfsmethoden

Die folgenden Methoden sind allgemeine Hilfsmethoden, die die Ausführung komplexer Vorgänge für Objekte im Datenmodell unterstützen. Während es möglich ist, diese Aktionen über andere Methoden für das Datenmodell oder seine Objekte auszuführen, erleichtern diese Methoden dies erheblich:

STDMETHOD(AcquireSubNamespace)(_In_ PCWSTR modelName, _In_ PCWSTR subNamespaceModelName, _In_ PCWSTR accessName, _In_opt_ IKeyStore *metadata, _COM_Outptr_ IModelObject **namespaceModelObject) PURE;

AcquireSubNamespace

Die AcquireSubNamespace-Methode hilft bei der Konstruktion von etwas, das eher wie ein Sprachnamespace aussieht als ein neues Objekt in einer dynamischen Sprache. Wenn ein Aufrufer für instance Eigenschaften eines Prozessobjekts kategorisieren möchte, um das Prozessobjekt besser zu organisieren und die Eigenschaften leichter zu ermitteln, besteht eine Methode dazu darin, ein Unterobjekt für jede Kategorie für das Prozessobjekt zu erstellen und diese Eigenschaften in diesem Objekt zu platzieren.

Siehe auch

Dieses Thema ist Teil einer Reihe, in der die Schnittstellen beschrieben werden, auf die über C++ zugegriffen werden kann, wie sie zum Erstellen einer C++-basierten Debuggererweiterung verwendet werden und wie andere Datenmodellkonstrukte (z. B. JavaScript oder NatVis) aus einer C++-Datenmodellerweiterung verwendet werden.

Debuggerdatenmodell C++-Übersicht

Debuggerdatenmodell-C++-Schnittstellen

Debuggerdatenmodell C++-Zusätzliche Schnittstellen

Debuggerdatenmodell-C++-Konzepte

Debuggerdatenmodell C++-Skripterstellung