Debugger Datenmodell C++ – Zusätzliche Schnittstellen
In diesem Thema werden einige zusätzliche Schnittstellen beschrieben, die dem Debugger Datenmodell C++ zugeordnet sind, z. B. Metadaten, Konzepte und Objektenumeration.
Debugger Datenmodell-Metadatenschnittstellen
Einer der Kernbegriffe im Datenmodell besteht darin, dass ein Objekt (insbesondere ein synthetisches Objekt) ein Wörterbuch für Schlüssel-/Wert-/Metadaten-Tupeln ist. Jeder Schlüssel kann über einen gesamten verknüpften Metadatenspeicher verfügen, der eine Vielzahl von Elementen beschreibt, die den Schlüssel und seinen potenziellen Wert umgeben. Beachten Sie, dass die Metadaten in keiner Weise den Wert des Schlüssels ändern. Es handelt sich nur um zusätzliche Informationen, die dem Schlüssel und seinem Wert zugeordnet sind, die sich auf die Präsentation oder andere zugeordnete Attribute des Schlüssels und dessen Wert auswirken können.
In einigen Fällen unterscheidet sich ein Metadatenspeicher überhaupt nicht von den Schlüssel-/Wert-/Metadaten-Tupeln, die der wesentliche Teil eines Objekts im Datenmodell sind. Er ist jedoch aus dieser Ansicht vereinfacht. Ein Metadatenspeicher wird durch die IKeyStore-Schnittstelle dargestellt. Es gibt zwar auch eine Sammlung von Schlüssel-/Wert-/Metadaten-Tupeln, aber es gibt Einschränkungen, was mit einem Metadatenschlüsselspeicher im Vergleich zu einem Modellobjekt geschehen kann:
- Ein Schlüsselspeicher kann nur über einen einzigen übergeordneten Speicher verfügen – er kann keine beliebige Kette von übergeordneten Modellen haben.
- Ein Schlüsselspeicher hat keine Konzepte. Er kann nur das Wörterbuch für Schlüssel-/Wert-/Metadaten-Tupeln enthalten. Dies bedeutet, dass die in einem Schlüsselspeicher vorhandenen Schlüssel statisch sind. Sie können nicht bei Bedarf von einem dynamischen Sprachsystem erstellt werden.
- Standardmäßig sind die Werte in einem metadatendefinierten Schlüsselspeicher nur auf grundlegende Werte (systeminterne und Eigenschaftenaccessoren) beschränkt.
Während ein Schlüsselspeicher eine beliebige Zahl (und beliebige Benennung) von Schlüsseln aufweisen kann, gibt es bestimmte Namen, die semantische Werte definiert haben. Derzeit sind diese Namen:
Schlüsselname | Typ | Beschreibung |
---|---|---|
PreferredRadix | Ganzzahl: 2, 8, 10 oder 16 | Gibt an, in welcher Basis ein Ordinalwert angezeigt werden soll |
PreferredFormat | Ganzzahl: wie durch die PreferredFormat-Enumeration definiert | Gibt den bevorzugten Formatierungstyp für die Anzeige des Werts an. |
PreferredLength | Ganzzahl | Gibt für Arrays und andere Container an, wie viele Elemente standardmäßig angezeigt werden sollen. |
FindDerivation | Boolean | Gibt an, ob der Debughost eine abgeleitete Typanalyse für den Wert vor der Verwendung ausführen soll (z. B. Anzeigen) |
Hilfe | String | QuickInfo-Hilfetext für den Schlüssel, der von der Benutzeroberfläche auf entsprechend hilfreiche Weise dargestellt werden kann. |
ActionName | String | Gibt an, dass die angegebene Methode (eine, die keine Argumente verwendet und keine Werte zurückgibt) eine Aktion ist. Der Name der Aktion wird in Metadaten angegeben. Eine Benutzeroberfläche kann diesen Namen verwenden, um die Option in einem Kontextmenü oder einer anderen geeigneten Benutzeroberfläche darzustellen. |
ActionIsDefault | Boolean | Nur gültig, wenn der ActionName-Schlüssel angegeben ist, gibt an, dass dies die Standardaktion für das Objekt ist. |
ActionDescription | String | Nur gültig, wenn der ActionName-Schlüssel angegeben ist, dies gibt eine QuickInfo-Formatbeschreibung für die Aktion an. Ein solcher Text kann von der Benutzeroberfläche auf entsprechend hilfreiche Weise dargestellt werden. |
Beachten Sie, dass obwohl Schlüssel im Metadatenspeicher ihre eigenen Metadaten (ad infinitum) haben können, es derzeit keine Verwendung für solche gibt. Die meisten Aufrufer geben null für alle Metadatenparameter in Methoden auf der IKeyStore-Schnittstelle an.
Die Kernmetadatenschnittstelle: IKeyStore
Die IKeyStore-Schnittstelle wird wie folgt definiert:
DECLARE_INTERFACE_(IKeyStore, IUnknown)
{
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(GetKeyValue)(_In_ PCWSTR key, _COM_Errorptr_opt_ IModelObject** object, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
STDMETHOD(SetKeyValue)(_In_ PCWSTR key, _In_ IModelObject* object) PURE;
STDMETHOD(ClearKeys)() PURE;
}
Die GetKey-Methode entspricht der GetKey-Methode für IModelObject. Gibt den Wert des angegebenen Schlüssels zurück, wenn er im Schlüsselspeicher oder im übergeordneten Speicher des Schlüsselspeichers vorhanden ist. Beachten Sie, dass, wenn es sich bei dem Wert des Schlüssels um einen Eigenschaftenaccessor handelt, die GetValue-Methode nicht für den Eigenschaftenaccessor aufgerufen wird. Es wird der eigentliche IModelPropertyAccessor zurückgegeben, der in ein IModelObject gepackt wurde. Es ist typisch, dass ein Client GetKeyValue aus diesem Grund aufruft.
Die SetKey-Methode entspricht der SetKey-Methode für IModelObject. Es ist die einzige Methode, die einen Schlüssel erstellen und ihm Metadaten innerhalb des Schlüsselspeichers zuordnen kann.
Die GetKeyValue-Methode ist die erste Methode, zu der ein Client greift, um den Wert eines bestimmten Schlüssels im Metadatenspeicher zu finden. Wenn der durch das Schlüsselargument angegebene Schlüssel innerhalb des Speichers (oder im übergeordneten Speicher) vorhanden ist, wird der Wert dieses Schlüssels und alle damit verbundenen Metadaten zurückgegeben. Wenn es sich bei dem Wert des Schlüssels um einen Eigenschaftenaccessor handelt (ein IModelPropertyAccessor, der in ein IModelObject gepackt wurde), wird die GetValue-Methode des Eigenschaftenaccessors automatisch von GetKeyValue aufgerufen, und der zugrunde liegende Wert der Eigenschaft wird zurückgegeben.
Die SetKeyValue-Methode entspricht der SetKeyValue-Methode für IModelObject. Diese Methode ist nicht in der Lage, einen neuen Schlüssel im Metadatenspeicher zu erstellen. Wenn ein Schlüssel vorhanden ist, wie durch das Schlüsselargument angegeben, wird der Wert wie angegeben festgelegt. Wenn es sich bei dem Schlüssel um einen Eigenschaftenaccessor handelt, wird die SetValue-Methode für den Eigenschaftenaccessor aufgerufen, um den zugrunde liegenden Wert festzulegen. Beachten Sie, dass Metadaten in der Regel statisch sind, sobald sie erstellt wurden. Diese Methode sollte nur selten auf einen Metadatenschlüsselspeicher angewendet werden.
Die ClearKeys-Methode entspricht der ClearKeys-Methode für IModelObject. Entfernt jeden Schlüssel aus dem angegebenen Metadatenspeicher. Diese Methode hat keine Auswirkungen auf einen übergeordneten Speicher.
Objektenumeration im Datenmodell
Aufzählen von Objekten im Datenmodell
Im Datenmodell gibt es zwei Kernschnittstellen der Schlüssel-Enumeration: IKeyEnumerator und IRawEnumerator. Dies sind zwar die beiden Kernschnittstellen, sie können jedoch zum Aufzählen von Objekten auf einem von drei Wegen verwendet werden:
Keys – Die IKeyEnumerator-Schnittstelle kann über einen Aufruf von EnumerateKeys abgerufen werden, um die Schlüssel eines Objekts und deren Werte/Metadaten aufzulisten, ohne zugrunde liegende Eigenschaftenaccessoren aufzulösen. Diese Aufzählungsart kann unformatierte IModelPropertyAccessor-Werte zurückgeben, die in IModelObjects enthalten sind.
Werte – Die IKeyEnumerator- und IRawEnumerator-Schnittstellen können über Aufrufe von EnumerateKeyValues oder EnumerateRawValues abgerufen werden, um die Schlüssel/Rohwerte für ein Objekt und deren Werte/Metadaten aufzählen zu können. Alle Eigenschaftenaccessoren, die in der Enumeration vorhanden sind, werden automatisch über einen Aufruf der zugrunde liegenden GetValue-Methode während einer solchen Enumeration aufgelöst.
Verweise – Die IKeyEnumerator- und IRawEnumerator-Schnittstellen können über Aufrufe von EnumerateKeyReferences oder EnumerateRawReferences abgerufen werden, um Verweise auf die Schlüssel/Rohwerte für ein Objekt aufzählen zu können. Solche Verweise können gespeichert und später zum Abrufen oder Festlegen des zugrunde liegenden Schlüssels oder Rohwerts verwendet werden.
KeyEnumerator: Enumeration von synthetischen Schlüsseln
Die IKeyEnumerator-Schnittstelle ist die einzige Schnittstelle für die Enumeration aller Schlüssel (nach Schlüssel, Wert oder Verweis) innerhalb eines Instanzobjekts und aller zugeordneten übergeordneten Modelle in der übergeordneten Modellkette. Die Schnittstelle wird wie folgt definiert:
DECLARE_INTERFACE_(IKeyEnumerator, IUnknown)
{
STDMETHOD(Reset)() PURE;
STDMETHOD(GetNext)(_Out_ BSTR* key, _COM_Errorptr_opt_ IModelObject** value, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
}
Die Reset-Methode setzt den Enumerator auf die Position zurück, an der er sich befand, als er zum ersten Mal aufgerufen wurde (z. B. vor dem ersten Element in der Enumeration). Bei einem nachfolgenden Aufruf von GetNext wird der erste aufgezählte Schlüssel zurückgegeben.
Die GetNext-Methode schiebt den Enumerator vorwärts und gibt den Schlüssel an dieser Position in der Enumeration zurück.
IRawEnumerator: Enumeration der systemeigenen oder zugrunde liegenden Sprachkonstrukte (C/C++)
Die IRawEnumerator-Schnittstelle ist die einzige Schnittstelle für die Enumeration aller systemeigenen/Sprachkonstrukte (nach Wert oder Verweis) innerhalb eines Objekts, welches ein systemeigenes Konstrukt innerhalb des Adressraums des Debugziels darstellt. Die Schnittstelle wird wie folgt definiert:
DECLARE_INTERFACE_(IRawEnumerator, IUnknown)
{
STDMETHOD(Reset)() PURE;
STDMETHOD(GetNext)(_Out_opt_ BSTR* name, _Out_opt_ SymbolKind *kind, _COM_Errorptr_opt_ IModelObject** value) PURE;
}
Die Reset-Methode setzt den Enumerator auf die Position zurück, an der er sich befand, als er zum ersten Mal aufgerufen wurde (z. B. vor dem ersten Element in der Enumeration). Ein nachfolgender Aufruf von GetNext gibt das erste aufgezählte systemeigene/Sprachkonstrukt zurück.
Die GetNext-Methode schiebt den Enumerator vorwärts und gibt das systemeigene/Sprachkonstrukt an dieser Position in der Enumeration zurück.
Weitere Informationen
Dieses Thema ist Teil einer Serie, in der die Schnittstellen beschrieben werden, auf die von C++ aus zugegriffen werden kann, und wie man sie verwendet, um eine C++ basierte Debugger-Erweiterung zu erstellen, und wie man andere Datenmodellkonstrukte (z. B. JavaScript oder NatVis) von einer C++ -Datenmodellerweiterung aus nutzen kann.
Debugger Datenmodell C++ – Übersicht
Debugger Datenmodell C++ – Schnittstellen
Debugger-Datenmodell-C++-Objekte
Debugger Datenmodell C++ – Zusätzliche Schnittstellen