Debugger Data Model C++ のオブジェクト
このトピックでは、Debugger Data Model C++ のオブジェクトを使用する方法と、デバッガーの機能を拡張する方法について説明します。
コア デバッガーのオブジェクト モデル
データ モデルの最も基本的で強力な点は、オブジェクト自体の定義と、オブジェクトとの相互作用する方法の定義が標準化されていることです。 IModelObject インターフェイスは、オブジェクトの概念をカプセル化します。そのオブジェクトが整数、浮動小数点値、文字列、デバッガーのターゲット アドレス空間内の何らかの複合型であっても、またはプロセスやモジュールの概念のようなデバッガーのコンセプトであってもすべてカプセル化されます。
IModelObject には、次のようなさまざまな項目を保持 (またはボックス化) できます。
組み込み値 - IModelObject には、8、16、32、または 64 ビットの符号付き整数または符号なし整数、ブール値、文字列、エラー、空の概念など、さまざまな基本型のコンテナーを指定できます。
ネイティブ オブジェクト - IModelObject は、デバッガーが対象としているもののアドレス空間内で、複合型 (デバッガーの型システムによって定義) を表すことができます
合成オブジェクト - IModelObject 動的オブジェクトにすることができます。いわば辞書のようなものであり、キー/値/メタデータ タプルのコレクションと、単純にキー/値のペアで表せない動作を定義するコンセプトのセットです。
プロパティ - IModelObject はプロパティを表すことができます。プロパティの値はメソッド呼び出しで取得または変更できます。 IModelObject 内のプロパティは、実際には IModelObject にボックス化された IModelPropertyAccessor インターフェイスです
メソッド - IModelObject は、一連の引数を使用して呼び出し、戻り値を取得できるメソッドを表すことができます。 IModelObject 内のメソッドは、実際には IModelObject にボックス化された IModelMethod インターフェイスです
オブジェクト モデル内の拡張性
IModelObject は、分離されたオブジェクトではありません。 上記のオブジェクトの種類の 1 つを表すだけでなく、各オブジェクトは親データ モデルのチェーンという概念を持っています。 このチェーンの動作は、JavaScript プロトタイプ チェーンとよく似ています。 各データ モデル オブジェクトは、JavaScript のようなプロトタイプの線形チェーンではなく、親モデルの線形チェーンを定義します。 これらの親モデルにはそれぞれ、独自の親セットの別の線形チェーンがあります。 要するに、各オブジェクトは、それ自身とこのツリー内のすべてのオブジェクトの機能(プロパティなど)の集合体です。 特定のプロパティを照会するときに、クエリ対象のオブジェクトがそのプロパティをサポートしていない場合、クエリは線形順に各親に順次渡されます。 これにより、集計ツリーの深さ優先検索を通じて、プロパティの検索が解決される動作が作成されます。
このオブジェクト モデル内の拡張性は、すべてのオブジェクトがそれ自身と親モデルのツリーの集合体であるというこの概念を考えれば、非常にシンプルです。 拡張機能を使用して、別のオブジェクトの親モデルのリストに自分自身を追加することができます。 これによりオブジェクトが拡張されます。 このようにして、オブジェクトや値の特定のインスタンスに加え、ネイティブ型、デバッガーにとってプロセスやスレッドとは何かというコンセプト、さらに ”反復可能なすべてのオブジェクト” という概念など、あらゆるものに機能を追加することができます。
コンテキストの 3 つの概念: this ポインター、アドレス空間、実装のプライベート データ
コンテキストには 3 つの概念があり、オブジェクトモデルのコンテキスト内で理解する必要があります。
コンテキスト: this ポインター
特定のプロパティまたはメソッドは、データ モデル ツリーのどのレベルでも実装できるため、メソッドやプロパティの実装では元のオブジェクト (C++ の this ポインター、JavaScript の this オブジェクト) にアクセスできる必要があります。 このインスタンス オブジェクトは、記述されているメソッドでコンテキストと呼ばれる最初の引数として、さまざまなメソッドに渡されます。
コンテキスト: アドレス空間
以前の拡張モデルでは、コンテキスト (ターゲット、プロセス、スレッド) が UI のコンセプトであり、すべての API が現在の UI の状態に相対的でしたが、データ モデル インターフェースでは、通常このコンテキストを IDebugHostContext インターフェースとして明示的または黙示的に取得することに注意してください。 データ モデル内の各 IModelObject には、この種類のコンテキスト情報が含まれており、そのコンテキストを返すオブジェクトにその情報を伝達できます。 つまり、IModelObject からネイティブ値やキー値を読み取ると、オブジェクトが最初に取得されたターゲットやプロセスが読み出されます。
また、USE_CURRENT_HOST_CONTEXT という明示的な定数値があり、IDebugHostContext 引数を取るメソッドに渡すことができます。 この値は、コンテキストが実際にデバッガーの現在の UI 状態であることを示します。 ただし、この概念は明示的である必要があります。
コンテキスト: プライベート データの実装
データ モデル内の各オブジェクトは、実際にはオブジェクト インスタンスと、接続されている親モデルのツリーの集合体です。 これらの各親モデル (さまざまなオブジェクトのチェーンでリンク可能) は、プライベート実装データを任意のインスタンス オブジェクトに関連付けることができます。 コンセプトによって作成された各 IModelObject には、特定の親モデルと、IUnknown インターフェイスによって定義されたプライベート インスタンス データをマッピングするハッシュ テーブルがあります。 これにより、親モデルはすべてのインスタンスに関する情報をキャッシュしたり、その他の任意のデータを関連付けたりすることができます。
この種類のコンテキストは、IModelObject の GetContextForDataModel メソッドと SetContextForDataModel メソッドを介してアクセスされます。
コア デバッガーのオブジェクト インターフェイス: IModelObject
The IModelObject インターフェイスは次のように定義されます。
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;
}
基本メソッド
以下では、IModelObject で表される任意の種類のオブジェクトに適用できる一般的なメソッドを示します。
STDMETHOD(GetKind)(_Out_ ModelObjectKind *kind) PURE;
STDMETHOD(GetContext)(_COM_Outptr_result_maybenull_ IDebugHostContext** context) PURE;
STDMETHOD(GetIntrinsicValue)(_Out_ VARIANT* intrinsicData);
STDMETHOD(GetIntrinsicValueAs)(_In_ VARTYPE vt, _Out_ VARIANT* intrinsicData) PURE;
STDMETHOD(Compare)(_In_ IModelObject* other, _COM_Outptr_opt_result_maybenull_ IModelObject **ppResult) PURE;
STDMETHOD(IsEqualTo)(_In_ IModelObject* other, _Out_ bool* equal) PURE;
STDMETHOD(Dereference)(_COM_Errorptr_ IModelObject** object) PURE;
GetKind メソッドは、IModelObject 内でボックス化されたオブジェクトの種類を返します。
GetContext メソッドは、オブジェクトに関連付けられているホスト コンテキストを返します。
GetIntrinsicValue メソッドは、IModelObject 内でボックス化されたオブジェクトを返します。 このメソッドは、ボックス化された組み込み要素またはボックス化された特定のインターフェイスを表す IModelObject インターフェイスでのみ、正当に呼び出すことができます。 ネイティブ オブジェクト、値オブジェクト、合成オブジェクト、および参照オブジェクトでは呼び出すことができません。 GetIntrinsicValueAs メソッドは、値を指定されたバリアント型に変換することを除き、GetIntrinsicValue メソッドと同じように動作します。 変換を実行できない場合、メソッドはエラーを返します。
IsEqualTo メソッドは、2 つのモデル オブジェクトを比較し、値が等しいかどうかを返します。 順序付けを持つオブジェクトの場合、このメソッドが true を返すことは、Compare メソッドが 0 を返すのと同じです。 順序付けはないが等しいオブジェクトの場合、Compare メソッドは失敗しますが、このメソッドは失敗しません。 値ベースの比較の意味は、オブジェクトの型によって定義されます。 現時点では、これは組み込み型とエラー オブジェクトに対してのみ定義されています。 現在、等値性を表すデータ モデルのコンセプトはありません。
Dereference メソッドは、オブジェクトを逆参照します。 このメソッドを使用すると、データ モデル ベースの参照 (ObjectTargetObjectReference、ObjectKeyReference) またはネイティブ言語参照 (ポインターまたは言語参照) を逆参照できます。 このメソッドでは、オブジェクトの単一レベルの参照セマンティクスが削除されることに注意してください。 たとえば、言語参照へのデータ モデル参照を使用することがよくあります。 そのような場合、Dereference メソッドを初めて呼び出すと、データ モデル参照が削除され、言語参照が残ります。 その結果のオブジェクトに対して逆参照を呼び出すと、言語参照が削除され、その参照のネイティブ値が返されます。
キー操作メソッド
キー、値、およびメタデータのタプルのディクショナリである合成オブジェクトには、それらのキー、値、およびそれらに関連付けられているメタデータを操作するための一連のメソッドがあります。
API の値ベースの形式は次のとおりです。
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;
API の参照ベースの形式は次のとおりです。
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 メソッドは、指定されたキーの値 (および関連付けられているメタデータ) を名前で取得するためにクライアントが最初に使用するメソッドです。 キーがプロパティ アクセサー (ボックス化された IModelPropertyAccessor である IModelObject の値) である場合、GetKeyValue メソッドは、実際の値を取得するために、プロパティ アクセサーの GetValue メソッドを自動的に呼び出します。
SetKeyValue メソッドは、キーの値を設定するためにクライアントが最初に設定するメソッドです。 このメソッドでは、オブジェクトに新しいキーを作成することはできません。 既存のキー値のみを設定できます。 多くのキーは読み取り専用であることに注意してください (キーは、たとえば SetValue メソッドから E_NOT_IMPL を返すプロパティ アクセサーによって実装されます)。 このメソッドは、読み取り専用キーで呼び出すと失敗します。
EnumerateKeyValues メソッドは、オブジェクトのすべてのキーを列挙するためにクライアントが最初に使用するメソッドです (これには、親モデルのツリー内の任意の場所に実装されているすべてのキーが含まれます)。 EnumerateKeyValues では、オブジェクト ツリー内の重複する名前で定義されているすべてのキーが列挙されることに注意してください。ただし、GetKeyValue や SetKeyValue などのメソッドは、深さ優先トラバーサルによって検出された名前のキーの最初のインスタンスのみが操作されます。
GetKey メソッドは、指定されたキーの値 (および関連付けられているメタデータ) を名前で取得します。 ほとんどのクライアントでは、代わりに GetKeyValue メソッドを使用する必要があります。 キーがプロパティ アクセサーの場合、このメソッドを呼び出すと、IModelObject にボックス化されたプロパティ アクセサー (IModelPropertyAccessor インターフェイス) が返されます。 GetKeyValue とは異なり、このメソッドは GetValue メソッドを呼び出しても、キーの基になる値が自動的に解決されません。 そのような解決は、呼び出し元の責任です。
SetKey メソッドは、オブジェクトにキーを作成するためにクライアントが使用するメソッドです (また、作成されたキーにメタデータを関連付けることができます)。 指定する名前のキーが対象のオブジェクトに既に含まれている場合は、2 つの動作のいずれかが発生します。 このキーが対象のインスタンス上にある場合、そのキーの値は元のキーを無視して置き換えられます。 一方、このキーが、このキーによって指定されたインスタンスの親データ モデルのチェーン内にある場合は、指定した名前の新しいキーが、このインスタンスに作成されます。 これにより、実際には、オブジェクトに同じ名前の 2 つのキーが割り当てられます (基本クラスと同じ名前のメンバーをシャドウする派生クラスに似ています)。
EnumerateKeys メソッドは、EnumerateKeyValues メソッドと同様に動作しますが、オブジェクトのプロパティ アクセサーが自動的に解決されない点が異なります。 つまり、キーの値がプロパティ アクセサーの場合、EnumerateKeys メソッドは、GetValue メソッドを自動的に呼び出すのではなく、IModelObject としてボックス化されたプロパティ アクセサー (IModelPropertyAccessorInterface) を返します。 これは、GetKey と GetKeyValue の違いに似ています。
ClearKeys メソッドは、このメソッドによって指定されたオブジェクトのインスタンスから、すべてのキーとその関連する値とメタデータを削除します。 このメソッドは、特定のオブジェクト インスタンスに接続されている親モデルには影響を与えません。
GetKeyReference メソッドは、指定された名前のキーをオブジェクト (またはその親モデル チェーン) 上で検索し、そのキーへの参照を IModelObject にボックス化された IModelKeyReference インターフェイスによる指定として返します。 その後、その参照を使用して、キーの値を取得または設定できます。
EnumerateKeyReferences メソッドは、列挙するキーへの参照 (IModelObject にボックス化された IModelKeyReference インターフェイスによって指定) を返す点を除き、EnumerateKeyReferences メソッドと同様に動作します。 このような参照を使用して、キーの基になる値を取得または設定できます。
コンセプト操作メソッド
モデル オブジェクトは、キー/値/メタデータタプルのディクショナリであると同時に、コンセプトのコンテナーでもあります。 コンセプトは、オブジェクトに対して、またはオブジェクトによって実行できる抽象的なものです。 コンセプトは、基本的には、オブジェクトがサポートするインターフェイスの動的ストアです。 現在、いくつかのコンセプトがデータ モデルによって定義されています。
コンセプト インターフェイス | 説明 |
---|---|
IDataModelConcept | コンセプトは親モデルです。 このモデルが、登録された型シグネチャを介してネイティブ型に自動的に接続される場合、その型の新しいオブジェクトがインスタンス化されるたびに、InitializeObject メソッドが自動的に呼び出されます。 |
IStringDisplayableConcept | オブジェクトは、表示用に文字列に変換できます。 |
IIterableConcept | オブジェクトはコンテナーであり、反復処理できます。 |
IIndexableConcept | オブジェクトはコンテナーであり、1 次元以上でインデックス化 (ランダム アクセス経由でアクセス) できます。 |
IPreferredRuntimeTypeConcept | オブジェクトは、そのオブジェクトから派生した型について基になる型システムが提供できる以上のことを理解しており、静的な型からランタイム型への変換を独自に処理できます。 |
IDynamicKeyProviderConcept | オブジェクトはキーの動的プロバイダーであり、コア データ モデルからすべてのキー クエリを引き継ぐ必要があります。 このインターフェイスは、通常、JavaScript などの動的言語へのブリッジとして使用されます。 |
IDynamicConceptProviderConcept | オブジェクトはコンセプトの動的プロバイダーであり、コア データ モデルからすべてのコンセプト クエリを引き継ぐ必要があります。 このインターフェイスは、通常、JavaScript などの動的言語へのブリッジとして使用されます。 |
IModelObject の次のメソッドは、オブジェクトによってサポートされているコンセプトを操作するために使用されます。
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 メソッドは、オブジェクト (またはその親モデル チェーン) のコンセプトを検索し、コンセプト インターフェイスへのインターフェイス ポインターを返します。 コンセプト インターフェイスの動作とメソッドは、各コンセプトに固有です。 ただし、多くのコンセプト インターフェイスでは、呼び出し元がコンテキスト オブジェクト (またはこのポインターを呼び出す可能性のあるもの) を明示的に渡す必要があることに注意してください。 すべてのコンセプト インターフェイスに正しいコンテキスト オブジェクトが渡されることを確認してください。
SetConcept メソッドを使用すると、このポインターによって指定されるオブジェクト インスタンス上に、指定されたコンセプトが配置されます。 親モデルがこのポインターによって指定されるオブジェクト インスタンスに接続されていて、同時にそのコンセプトをサポートしている場合、インスタンスでの実装により、親モデル内のコンセプトがオーバーライドされます。
ClearConcepts メソッドは、このメソッドによって指定されたオブジェクトのインスタンスからすべてのコンセプトを削除します。
ネイティブ オブジェクト メソッド
多くのモデル オブジェクトは組み込み関数 (整数、文字列など) または合成コンストラクト (キー/値/メタデータタプルとコンセプトのディクショナリ) を参照しますが、モデル オブジェクトはネイティブ コンストラクト (デバッグ ターゲットのアドレス空間内のユーザー定義型など) を参照することもできます。 IModelObject インターフェイスには、このようなネイティブ オブジェクトに関する情報にアクセスするための一連のメソッドがあります。 それらのメソッドは次のとおりです。
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 メソッドは、指定されたオブジェクト内のネイティブ コンストラクトを検索します。 このようなコンストラクトは、フィールド、基本クラス、基本クラス内のフィールド、メンバー関数などです。
EnumerateRawValues メソッドは、指定されたオブジェクトのすべてのネイティブの子 (フィールド、基底クラスなど) を列挙します。
TryCastToRuntimeType メソッドは、デバッグ ホストに分析の実行を要求し、特定のオブジェクトの実際のランタイムの種類 (ほとんどの派生クラスなど) を決定します。 使用される正確な分析はデバッグ ホストに固有であり、RTTI (C++ ランタイム型情報)、オブジェクトの V-Table (仮想関数テーブル) 構造体の検査、またはホストが静的な型から動的/ランタイム型を確実に判別するために使用できるその他の手段を含めることができます。 ランタイム型への変換に失敗しても、このメソッドの呼び出しは失敗しません。 このような場合、メソッドは出力引数で指定されたオブジェクト (this ポインター) を返します。
GetLocation メソッドは、ネイティブ オブジェクトの場所を返します。 ネイティブ オブジェクトの場所は通常、デバッグ ターゲットのアドレス空間内の仮想アドレスですが、そうでない場合もあります。 このメソッドによって返される場所は、仮想アドレス、レジスタまたはサブレジスタ内の配置を示す、またはデバッグ ホストによって定義されている他の任意のアドレス空間を示す抽象場所です。 結果の Location オブジェクトの HostDefined フィールドが 0 の場合は、その場所が実際には仮想アドレスであることを示します。 このような仮想アドレスは、結果の場所の Offset フィールドを調べることで取得できます。 HostDefined フィールドの 0 以外の値は、オフセット フィールドがそのアドレス空間内のオフセットである代替アドレス空間を示します。 ここでの 0 以外の HostDefined 値の正確な意味は、デバッグ ホストに対してプライベートです。
GetTypeInfo メソッドは、指定されたオブジェクトのネイティブ型を返します。 オブジェクトにネイティブ型情報が関連付けられていない場合 (たとえば、組み込み関数など)、呼び出しは成功しますが、null が返されます。
GetTargetInfo メソッドは、実際には、指定されたオブジェクトのネイティブ型と抽象場所の両方を返す GetLocation メソッドと GetTypeInfo メソッドの組み合わせです。
GetRawReference メソッドは、指定されたオブジェクト内のネイティブ コンストラクトを検索し、そのオブジェクトへの参照を返します。 このようなコンストラクトは、フィールド、基本クラス、基本クラス内のフィールド、メンバー関数などです。ここで返される参照 (ObjectTargetObjectReference 型のオブジェクト) と言語参照 (C++ & や && スタイル参照など) を区別することが重要です。
EnumerateRawReferences メソッドは、指定されたオブジェクトについて、すべてのネイティブの子 (フィールド、基底クラスなど) への参照を列挙します。
機能拡張メソッド
前述のように、モデル オブジェクトは JavaScript オブジェクトおよびそのプロトタイプ チェーンとよく似た動作をします。 特定の IModelObject インターフェイスによって表わされるインスタンスに加え、任意の数の親モデルがオブジェクトに接続されている場合があります (それぞれの親モデルに、さらに任意の数の親モデルが接続されていることもあります)。 これは、データ モデル内の拡張性を実現するための主要な手段です。 特定のプロパティまたはコンセプトを特定のインスタンス内に配置できない場合は、インスタンスをルートとするオブジェクト ツリー (親モデルによって定義) の深さ優先検索が実行されます。
次の各メソッドは、特定の IModelObject インスタンスに関連付けられている親モデルのチェーンを操作します。
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 メソッドは、指定されたオブジェクト インスタンスに接続されている親モデルの数を返します。 親モデルは、親モデル チェーンの線形順序で、深さ優先のプロパティを検索します。
GetParentModel メソッドは、指定されたオブジェクトの親モデル チェーン内の i 番目の親モデルを返します。 親モデルは、追加または列挙される線形順序でプロパティまたはコンセプトを検索します。 インデックス i が 0 の親モデルは、インデックス i + 1 の親モデルの前に (階層的に) 検索されます。
AddParentModel メソッドは、指定されたオブジェクトに新しい親モデルを追加します。 このようなモデルは、検索チェーンの末尾 (override 引数を false に指定) または検索チェーンの先頭 (override 引数を true に指定) に追加できます。 さらに、各親モデルは、必要に応じて、特定の親 (またはその親階層内のすべてのユーザー) のプロパティまたはコンセプトのコンテキスト (このポインターのセマンティック) を調整できます。 コンテキスト調整はほとんど使用されませんが、オブジェクトの埋め込み、名前空間の構築などの強力なコンセプトが使用できるようになります。
RemoveParentModel は、指定したオブジェクトの親検索チェーンから指定した親モデルを削除します。
SetContextForDataModel メソッドは、データモデルの実装がインスタンス オブジェクトに実装データを配置するために使用します。 コンセプト的には、各 IModelObject (わかりやすいように、”インスタンス” と呼びます) に、状態のハッシュ テーブルが含まれています。 ハッシュ テーブルは、インスタンスの親モデル階層にある別の IModelObject (わかりやすいように、”データ モデル” と呼びます) によってインデックス化されます。 このハッシュに含まれる値は、IUnknown インスタンスによって表される参照カウント状態情報のセットです。 データ モデルはインスタンスにこの状態を設定すると、任意の実装データを保存して、プロパティ ゲッター時などに取り出せるようになります。
GetContextForDataModel メソッドは、SetContextForDataModel の事前呼び出しで設定されたコンテキスト情報を取得するために使用されます。 これにより、インスタンス オブジェクトの親モデル階層のデータ モデルによってインスタンス オブジェクトに設定された状態情報が取得されます。 このコンテキスト/状態とその意味の詳細については、SetContextForDataModel のドキュメントを参照してください。
Debugger Data Model のコア オブジェクト型
データ モデル内のオブジェクトは、.NET のオブジェクトの概念に似ています。 これは、データ モデルが認識するコンストラクトをボックス化できる汎用コンテナーです。 ネイティブ オブジェクトと合成 (動的) オブジェクトに加え、IModelObject のコンテナーに配置 (またはボックス化) できる一連のコア オブジェクトの型があります。 これらの値の大部分は、標準のコンテナーである COM/OLE VARIANT に配置され、その VARIANT に何を含めることができるかについて、いくつかの追加の制限が適用されます。 これらの最も基本的な種類は次のとおりです。
- 8 ビット符号なし値と符号付き値 (VT_UI1、VT_I1)
- 16 ビット符号なし値と符号付き値 (VT_UI2、VT_UI2)
- 32 ビット符号なし値と符号付き値 (VT_UI4、VT_I4)
- 64 ビット符号なし値と符号付き値 (VT_UI8、VT_I8)
- 単精度浮動小数点値と倍精度浮動小数点値 (VT_R4、VT_R8)
- 文字列 (VT_BSTR)
- ブール値 (VT_BOOL)
これらの基本型に加え、格納されている IUnknown が特定のインターフェイスを実装することが保証されている場合は、VT_UNKNOWN によって定義された複数のコア データ モデル オブジェクトが IModelObject に配置されます。 これらの型には、次のようなものがあります。
- プロパティ アクセサー (IModelPropertyAccessor)
- メソッド オブジェクト (IModelMethod)
- キー参照オブジェクト (IModelKeyReference または IModelKeyReference2)
- コンテキスト オブジェクト (IDebugModelHostContext)
プロパティ アクセサー: IModelPropertyAccessor
データ モデルのプロパティ アクセサーは、IModelObject にボックス化された IModelPropertyAccessor インターフェイスの実装です。 モデル オブジェクトに対してクエリを実行すると、いずれかの種類の ObjectPropertyAccessor が返されます。組み込み値は IModelPropertyAccessor に対してクエリ可能であることが保証される VT_UNKNOWN です。 プロセスでは、IModelPropertyAccessor に静的にキャスト可能であることが保証されます。
プロパティ アクセサーは、データ モデルでキー値を取得および設定するためのメソッド呼び出しを取得する間接的な方法です。 特定のキーの値がプロパティ アクセサーの場合、GetKeyValue メソッドと SetKeyValue メソッドはこれを自動的に認識し、必要に応じてプロパティ アクセサーの基になる GetValue メソッドまたは SetValue メソッドを呼び出します。
IModelPropertyAccessor インターフェイスは次のように定義されます。
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 メソッドは、プロパティ アクセサーのゲッターです。 クライアントがプロパティの基になる値をフェッチしようとするたびに呼び出されます。 プロパティ アクセサーを直接取得する呼び出し元は、キー名と正確なインスタンス オブジェクト (this ポインター) をプロパティ アクセサーの GetValue メソッドに渡す役割を担うことに注意してください。
SetValue メソッドは、プロパティ アクセサーのセッターです。 クライアントが基になるプロパティに値を割り当てるたびに呼び出されます。 多くのプロパティは読み取り専用です。 読み取り専用の場合、SetValue メソッドを呼び出すと E_NOTIMPL が返されます。 プロパティ アクセサーを直接取得する呼び出し元は、キー名と正確なインスタンス オブジェクト (this ポインター) をプロパティ アクセサーの SetValue メソッドに渡す役割を担うことに注意してください。
メソッド: IModelMethod
データ モデルのメソッドは、IModelObject にボックス化された IModelMethod インターフェイスの実装です。 モデル オブジェクトに対してクエリを実行すると、いずれかの種類の ObjectMethod が返されます。組み込み値は IModelMethod に対してクエリ可能であることが保証される VT_UNKNOWN です。 プロセスでは、IModelMethod に静的にキャスト可能であることが保証されます。 データ モデル内のすべてのメソッドは、本質的に動的です。 0 個以上の引数のセットを入力として受け取り、1 つの出力値を返します。 オーバーロードの解決法はなく、パラメーター名、型、または期待に関するメタデータもありません。
IModelMethod インターフェイスは次のように定義されます。
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 メソッドは、データ モデルで定義されているすべてのメソッドを呼び出す方法です。 呼び出し元は、正確なインスタンス オブジェクト (this ポインター) と任意の引数のセットを渡す役割を担います。 メソッドの結果と、その結果に関連付けられている任意のメタデータが返されます。 値を論理的に返さないメソッドであっても、有効な IModelObject を返す必要があります。 このような場合、IModelObject はボックス化された値がありません。 メソッドが失敗した場合、オプションの拡張エラー情報が入力引数に返されることがあります (返された HRESULT が失敗した場合を含む)。 呼び出し元は、返されているかどうかを確認する必要があります。
キー参照: IModelKeyReference または IModelKeyReference2
キー参照は、要するに、特定のオブジェクトにあるキーへのハンドルです。 クライアントは、GetKeyReference などのメソッドを使用してこのようなハンドルを取得し、後でハンドルを使用することで、必ずしも元のオブジェクトを保持せずにキーの値を取得または設定できます。 この種類のオブジェクトは、IModelObject にボックス化された IModelKeyReference または IModelKeyReference2 インターフェイスの実装です。 モデル オブジェクトに対してクエリを実行すると、いずれかの種類の ObjectKeyReference が返されます。その場合、組み込み値は IModelKeyReference に対してクエリ可能であることが保証される VT_UNKNOWN です。 プロセスでは、IModelKeyReference に静的にキャスト可能であることが保証されます。
キー参照インターフェイスは次のように定義されます。
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 メソッドは、このキー参照がハンドルであるキーの名前を返します。 返される文字列は標準の BSTR であり、SysFreeString の呼び出しを介して解放する必要があります。
GetOriginalObject メソッドは、キー参照の作成元のインスタンス オブジェクトを返します。 キー自体がインスタンス オブジェクトの親モデル上にある可能性があることに注意してください。
GetContextObject メソッドは、対象のキーがプロパティ アクセサーを参照している場合に、プロパティ アクセサーの GetValue メソッドまたは SetValue メソッドに渡されるコンテキスト (this ポインター) を返します。 ここで返されるコンテキスト オブジェクトは、GetOriginalObject からフェッチされた元のオブジェクトと同じである場合もあれば、異なる場合もあります。 キーが親モデル上にあり、その親モデルに関連付けられたコンテキスト調整機能が存在する場合、元のオブジェクトがインスタンスオブジェクトとなり、GetKeyReference または EnumerateKeyReferences が呼び出されます。 コンテキスト オブジェクトは、元のオブジェクトと、このキー参照をハンドルとするキーが格納された親モデルとの間の、最終的なコンテキスト調整機能から生じるすべての項目です。 コンテキスト調整機能がない場合、元のオブジェクトとコンテキスト オブジェクトは同じになります。
キー参照の GetKey メソッドは、IModelObject の GetKey メソッドと同様に動作します。 基になるキーの値と、キーに関連付けられているメタデータが返されます。 キーの値がプロパティ アクセサーである場合は、IModelObject にボックス化されたプロパティ アクセサー (IModelPropertyAccessor) が返されます。 このメソッドは、プロパティ アクセサーで基になる GetValue メソッドまたは SetValue メソッドを呼び出しません。
キー参照の GetKeyValue メソッドは、IModelObject の GetKeyValue メソッドと同様に動作します。 基になるキーの値と、キーに関連付けられているメタデータが返されます。 キーの値がプロパティ アクセサーである場合は、プロパティ アクセサーの基になる GetValue メソッドが自動的に呼び出されます。
キー参照の SetKey メソッドは、IModelObject の SetKey メソッドと同様に動作します。 キーの値が割り当てられます。 元のキーがプロパティ アクセサーの場合は、プロパティ アクセサーが置き換えられます。 プロパティ アクセサーで SetValue メソッドを呼び出すことはありません。
キー参照の SetKeyValue メソッドは、IModelObject の SetKeyValue メソッドと同様に動作します。 キーの値が割り当てられます。 元のキーがプロパティ アクセサーであった場合、プロパティ アクセサー自体を置き換えるのではなく、基になる SetValue メソッドをプロパティ アクセサーで呼び出します。
OverrideContextObject メソッド (IModelKeyReference2 にのみ存在) は、このキー参照が基になるプロパティ アクセサーの GetValue メソッドまたは SetValue メソッドに渡すコンテキスト オブジェクトを永続的に変更するために使用される高度なメソッドです。 このメソッドに渡されたオブジェクトは、GetContextObject の呼び出しからも返されます。 このメソッドは、スクリプト プロバイダーが特定の動的言語の動作をレプリケートするために使用できます。 このメソッドは、一部のクライアントを除いて呼び出さないでください。
コンテキスト オブジェクト: IDebugHostContext
コンテキスト オブジェクトは、デバッグ ホストが (データ モデルと連携して) すべてのオブジェクトに関連付ける情報の不透明な BLOB です。 たとえば、プロセス コンテキストや、情報の取得元のアドレス空間などがコンテキスト オブジェクトとなります。コンテキスト オブジェクトは、IModelObject 内でボックス化された IDebugHostContext の実装です。 IDebugHostContext はホスト定義インターフェイスであることに注意してください。 クライアントがこのインターフェイスを実装することはありません。
コンテキスト オブジェクトの詳細については、「Debugger Data Model C++ のインターフェイス」の「Debugger Data Model C++ のホスト インターフェイス」を参照してください。
データ モデル マネージャー
データ モデル マネージャー IDataModelManager2 (または以前の IDataModelManager) へのコア インターフェイスは、次のように定義されています。
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;
}
管理メソッド
次の一連のメソッドは、データ モデルをホストするアプリケーション (デバッガーなど) によって使用されます。
STDMETHOD(Close)() PURE;
Close メソッドは、データ モデル マネージャーのシャットダウン プロセスを開始するためにデータ モデルをホストするアプリケーション (デバッガーなど) がデータ モデル マネージャーで呼び出されます。 データ モデルのホストが、Close メソッドを使用せずにデータ モデル マネージャー上の最終参照を解放すると、データ モデルの管理インフラストラクチャからの重大なリークをはじめとする想定外の動作が発生する可能性があります。
オブジェクトの作成/ボックス化メソッド
次の一連のメソッドは、新しいオブジェクトの作成や、IModelObject (データ モデルのコア インターフェイス) への値のボックス化に使用されます。
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 メソッドは、"値なし" オブジェクトを作成し、それを IModelObject にボックス化して返します。 返されるモデル オブジェクトの種類は ObjectNoValue です。
"値なし" オブジェクトには、いくつかの意味があります。
- (言語によっては)、void、null、undefined と意味的に同等と考えることができます
- プロパティ アクセサーの GetValue メソッドが成功を返し、結果として "値なし" オブジェクトを返す場合は、特定のプロパティに特定のインスタンスの値が存在しないことを意味し、その特定のインスタンスのプロパティを存在しないものとして扱う必要があります。
- 意味的に戻り値を持たないデータ モデル メソッドでは、これをセンチネルとして使用して示します (メソッドは有効な IModelObject を返す必要があるため)。
CreateErrorObject メソッドは、"Error オブジェクト" を作成します。 データ モデルには、例外と例外フローの概念はありません。 エラーは、次の 2 つの方法でプロパティ/メソッドから発生します。
- 拡張エラー情報のない 1 つの失敗した HRESULT。 エラーに対して提供できる情報がそれ以上ないか、エラー自体が返された HRESULT から自明です。
- 拡張エラー情報のある 1 つの失敗した HRESULT。 拡張エラー情報は、プロパティ/メソッドの出力引数で返されるエラー オブジェクトです。
CreateTypedObject メソッドは、クライアントがデバッグ ターゲットのアドレス空間にネイティブ/言語オブジェクトの表現を作成するためのメソッドです。 新しく作成されたオブジェクトの型 (objectType 引数で示される) が、正規ビジュアライザーまたは拡張機能としてデータモデル マネージャに登録された 1 つ以上の型シグネチャと一致する場合、それらの一致するデータ モデルは、作成されたインスタンス オブジェクトに自動的に接続された後、呼び出し元に返されます。
CreateTypedObjectReference メソッドは、基になるネイティブ/言語コンストラクトへの参照を作成することを除き、意味的には CreateTypedObject メソッドに似ています。 作成された参照は、いずれかの種類の ObjectTargetObjectReference を持つオブジェクトです。 基になる言語 (C++ &や && など) がサポートする可能性があるため、ネイティブ参照ではありません。 C++ 参照への ObjectTargetObjectReference を持つことは十分に可能です。 ObjectTargetObjectReference の種類のオブジェクトは、IModelObject で Dereference メソッドを使用することで、基になる値に変換できます。 また、基になるホストの式エバリュエーターに参照を渡して、適切な方法で値に割り当て直すこともできます。
CreateSyntheticObject メソッドは、空のデータ モデル オブジェクト (キー/値/メタデータのタプルとコンセプトのディクショナリ) を作成します。 作成時には、オブジェクトにキーやコンセプトはありません。 呼び出し元が利用できる白紙の状態です。
CreateDataModelObject メソッドは、データ モデルであるオブジェクト (親モデルとして他のオブジェクトに接続されるオブジェクト) を作成するための単純なヘルパー ラッパーです。 このようなオブジェクトはすべて、IDataModelConcept を介してデータ モデルのコンセプトをサポートする必要があります。 このメソッドは、明示的なコンテキストを持たない新しい空白の合成オブジェクトを作成し、渡された IDataModelConcept を、新しく作成されたオブジェクトのデータ モデルのコンセプトの実装として追加します。 これは、CreateSyntheticObject と SetConcept の呼び出しでも同様に実現できます。
CreateIntrinsicObject メソッドは、組み込み値を IModelObject にボックス化するメソッドです。 呼び出し元は COM VARIANT に値を配置し、このメソッドを呼び出します。 データ モデル マネージャーは、オブジェクトを表す IModelObject を返します。 このメソッドが、プロパティ アクセサー、メソッド、コンテキストなどの基本的な IUnknown ベースの型をボックス化するためにも使用されることに注意してください。このような場合、IUnknown ベースのコンストラクトの種類は objectKind メソッドによって示され、渡されたバリアントの punkVal フィールドは IUnknown 派生型です。 この型は、プロセス内の適切なモデル インターフェイス (IModelPropertyAccessor、IModelMethod、IDebugHostContext など) に静的にキャストできる必要があります。 このメソッドでサポートされる VARIANT 型は、VT_UI1、VT_I1、VT_UI2、VT_I2、VT_UI4、VT_I4、VT_UI8、VT_I8、VT_R4、VT_R8、VT_BOOL、VT_BSTR、および VT_UNKNOWN です (列挙型 ModelObjectKind で示される特殊な IUnknown 派生型のセットの場合)。
CreateTypedintrinsicObject メソッドは CreateIntrinsicObject メソッドに似ていますが、ネイティブ/言語型をデータに関連付け、ボックス化された値と共に実行できる点が異なります。 これにより、データ モデルはネイティブ列挙型 (単に VT_UI* または VT_I* 値) などのコンストラクトを表すことができます。 ポインター型もこのメソッドを使用して作成されます。 データ モデルのネイティブ ポインターは、デバッグ ターゲットの仮想アドレス空間へのオフセットを表す 0 個の拡張 64 ビット数量です。 VT_UI8 内にボックス化され、このメソッドとネイティブ/言語ポインターを示す型を使用して作成されます。
CreateMetadataStore メソッドは、キー ストア (キー/値/メタデータ タプルの簡略化されたコンテナー) を作成します。これは、プロパティやその他のさまざまな値に関連付けることができるメタデータを保持するために使用されます。 メタデータ ストアには 1 つの親を含むことができます (つまり、1 つの親を持つことができます)。 特定のメタデータ キーが特定のストアに存在しない場合、その親はチェックされます。 ほとんどのメタデータ ストアには親がありません。 ただし、共通のメタデータを簡単に共有する方法が提供されています。
CreateTypedIntrinsicObjectEx メソッドは、意味的には CreateTypedIntrinsicObject メソッドに似ています。 これら 2 つの唯一の違いは、このメソッドを使用では、組み込みデータが有効なコンテキストを呼び出し元が指定できる点です。 コンテキストが渡されない場合、そのデータは型引数から継承されたすべてのコンテキスト (CreateTypedIntrinsicObject の動作) で有効なものとして扱われます。 これにより、型から継承できるよりも具体的なコンテキストを必要とする型指定されたポインター値をデバッグ ターゲットに作成できます。
機能拡張/登録メソッド 次の各メソッドは、データ モデルの拡張メカニズムを管理します。これにより、クライアントは既存のモデルを拡張または登録したり、特定の条件に一致するネイティブ型に特定の親モデルを自動的に接続するようにデータ モデルに要求したりできます。
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 メソッドは、RegisterModelForTypeSignature メソッドの事前呼び出し時に特定の型シグネチャに対して登録されたデータ モデルを返します。 このメソッドから返されるデータ モデルは、渡された型シグネチャに一致するすべての型の正規ビジュアライザーとして扱われます。 そのデータ モデルが、正規のビジュアライザーとして型の表示を引き継ぎます。 表示エンジンは、既定では、データ モデルによって表示されるオブジェクトのビューを優先して、オブジェクトのネイティブ/言語コンストラクトを非表示にします。
GetModelForType メソッドは、特定の型インスタンスの正規ビジュアライザーであるデータ モデルを返します。 実際には、このメソッドは、RegisterModelForTypeSignature メソッドの事前呼び出しによって登録された、最もよく一致する型シグネチャを検索し、関連付けられているデータ モデルを返します。
RegisterModelForTypeSignature メソッドは、呼び出し元が特定の型 (または型のセット) の正規ビジュアライザーを登録するために使用する主要なメソッドです。 正規ビジュアライザーは、実際には、特定の型 (または一連の型) の表示を引き継ぐデータ モデルです。 デバッガー のユーザー インターフェイスに表示される型のネイティブ/言語ビューの代わりに、登録されたデータ モデルによって表示される型のビューが表示されます (ユーザーの希望に応じて、ネイティブ/言語ビューに戻ることもできます)。
UnregisterModelForTypeSignature
UnregisterModelForTypeSignature メソッドは、RegisterModelForTypeSignature メソッドの事前呼び出しを元に戻します。 このメソッドは、特定の型シグネチャに一致する型の正規ビジュアライザーとして特定のデータ モデルを削除するか、そのデータ モデルが登録されているすべての型シグネチャの正規ビジュアライザーとして特定のデータ モデルを削除できます。
RegisterExtensionForTypeSignature
RegisterExtensionForTypeSignature メソッドは RegisterModelForTypeSignature メソッドに似ていますが、1 つの重要な違いがあります。 このメソッドに渡されるデータ モデルは、どの型の正規ビジュアライザーでもなく、その型のネイティブ/言語ビューの表示を引き継ぐものではありません。 このメソッドに渡されるデータ モデルは、指定された型シグネチャに一致する具象型の親として自動的に追加されます。 RegisterModelForTypeSignature メソッドとは異なり、同一またはあいまいな型シグネチャが、特定の型 (または型のセット) の拡張機能として登録されることは制限されていません。 拡張機能の型シグネチャが、与えられた具象型のインスタンスに一致する場合、このメソッドによって登録されたデータ モデルが、新しく作成されたオブジェクトに親モデルとして自動的に接続されます。 これにより、実際には、任意の数のクライアントが新しいフィールドまたは機能を使用して型 (または型のセット) を拡張できます。
UnregisterExtensionForTypeSignature
UnregisterExtensionForTypeSignature メソッドは、RegisterExtensionForTypeSignature の事前呼び出しを元に戻します。 特定の型シグネチャの拡張機能として、またはデータ モデルが登録されたすべての型シグネチャの拡張機能として、特定のデータ モデルの登録を解除します。
GetRootNamespace メソッドは、データ モデルのルート名前空間を返します。 これは、データ モデルが管理し、デバッグ ホストが特定のオブジェクトを配置するオブジェクトです。
RegisterNamedModel メソッドを使用して、特定のデータ モデルを周知の名前で登録すると、そのデータ モデルを拡張しようとするクライアントがこのデータ モデルを見つけやすくなります。 これが API の主目的です。公開されたデータ モデルは、周知の登録名のモデルを取得し、親モデルをそれに追加することによって拡張できます。
UnregisterNamedModel メソッドは、RegisterNamedModel の事前呼び出しを元に戻します。 データ モデルと、そのモデルを検索できる名前の間の関連付けが削除されます。
呼び出し元が、特定の登録名のデータ モデルを拡張しようとする場合、AcquireNamedModel メソッドを呼び出して、拡張するデータ モデル用のオブジェクトを取得します。 このメソッドは、RegisterNamedModel メソッドの事前呼び出しによって登録されたデータ モデルを返します。 AcquireNamedModel メソッドの主な目的はモデルを拡張することです。このメソッドは、指定された登録名のモデルがまだ存在しない場合に特別な動作をします。 指定された登録名のモデルがまだ存在しない場合、スタブ オブジェクトが作成され、指定された名前で一時的に登録されて、呼び出し元に返されます。 RegisterNamedModel メソッドの呼び出しによって実際のデータ モデルが登録されると、スタブ オブジェクトに対して加えられた変更内容が実際のモデルに反映されます。 これにより、相互に拡張されるコンポーネントで、読み込み順序の依存関係に関する多くの問題が解消されます。
ヘルパー メソッド
次のメソッドは、データ モデル内のオブジェクトに対する複雑な操作の実行を支援する一般的なヘルパー メソッドです。 データ モデルやそのオブジェクトに対して他のメソッドを使用してこれらの処理を実行することもできますが、これらの便利なメソッドを使用した方がはるかに容易です。
STDMETHOD(AcquireSubNamespace)(_In_ PCWSTR modelName, _In_ PCWSTR subNamespaceModelName, _In_ PCWSTR accessName, _In_opt_ IKeyStore *metadata, _COM_Outptr_ IModelObject **namespaceModelObject) PURE;
AcquireSubNamespace メソッドは、動的言語の新しいオブジェクトの構築よりも、言語名前空間のような従来型のオブジェクトを構築するのに便利です。 たとえば、呼び出し元がプロセス オブジェクトのプロパティを分類してプロセス オブジェクトをさらに整理することで、プロパティの検出を容易にする場合、これを行う 1 つの方法として、プロセス オブジェクトのカテゴリごとにサブオブジェクトを作成し、そのオブジェクト内にそれらのプロパティを配置することができます。
関連項目
このトピックは、C++ からアクセスできるインターフェイス、それらを使用して C++ ベースのデバッガー拡張機能を構築する方法、および C++ データ モデル拡張機能から他のデータ モデル構造 (JavaScript や NatVis など) を利用する方法を説明するシリーズの一部です。
Debugger Data Model C++ のインターフェイス
Debugger Data Model C++ のその他のインターフェイス