このトピックでは、デバッガー データ モデルの C++ インターフェイスを使用してデバッガーの機能を拡張およびカスタマイズする方法の概要について説明します。
デバッガー データ モデル C++ ホスト インターフェイス
デバッガー データ モデル ホスト を する
デバッガー データ モデルは、さまざまなコンテキストでホストできるコンポーネント化されたシステムとして設計されています。 通常、データ モデルはデバッガー アプリケーションのコンテキストでホストされます。 データ モデルのホストにするには、デバッガーの主要な側面 (ターゲット設定、メモリ空間、エバリュエーター、シンボリック システム、型システムなど) を公開するために、多くのインターフェイスを実装する必要があります。これらのインターフェイスは、データ モデルをホストする任意のアプリケーションによって実装されますが、コア データ モデルと、データ モデルと相互運用する拡張機能の両方によって使用されます。
コア インターフェイスのセットは次のとおりです。
| インターフェイス名 | 説明 |
|---|---|
| IDebugHost | デバッグ ホストへのコア インターフェイス。 |
| IDebugHostStatus | クライアントがホストの状態を照会できるようにするインターフェイス。 |
| IDebugHostContext | ホスト内のコンテキストの抽象化 (たとえば、特定のターゲット、特定のプロセス、特定のアドレス空間など)。 |
| IDebugHostErrorSink | ホストとデータ モデルの特定の部分からエラーを受信するために呼び出し元によって実装されるインターフェイス |
| IDebugHostEvaluator / IDebugHostEvaluator2 | デバッグ ホストの式エバリュエーター。 |
| IDebugHostExtensibility | ホストまたはホストの一部 (式エバリュエーターなど) の機能を拡張するためのインターフェイス。 |
型システムインターフェイスとシンボリック インターフェイスは次のとおりです。
| InterfaceName | 説明 |
|---|---|
| IDebugHostSymbols | シンボルへのアクセスと解決を提供するコア インターフェイス |
| IDebugHostSymbol / IDebugHostSymbol2 | 任意の種類の 1 つのシンボルを表します。 特定のシンボルは、このインターフェイスの派生です。 |
| IDebugHostModule | プロセス内で読み込まれたモジュールを表します。 これは一種のシンボルです。 |
| IDebugHostType / IDebugHostType2 | ネイティブ/言語型を表します。 |
| IDebugHostConstant | シンボリック情報内の定数を表します (C++ の型以外のテンプレート引数など)。 |
| IDebugHostField | 構造体またはクラス内のフィールドを表します。 |
| IDebugHostData | モジュール内のデータを表します (構造体またはクラス内では IDebugHostField になります) |
| IDebugHostBaseClass | 基底クラスを表します。 |
| IDebugHostPublic | PDB の publics テーブル内のシンボルを表します。 これには型情報が関連付けされていません。 名前とアドレスです。 |
| IDebugHostModuleSignature | モジュールシグネチャを表します。名前またはバージョンによってモジュールのセットと一致する定義です。 |
| IDebugHostTypeSignature | 型シグネチャを表します。モジュールや名前によって一連の型と一致する定義です。 |
コア ホスト インターフェイスの : IDebugHost
IDebugHost インターフェイスは、任意のデータ モデル ホストのコア インターフェイスです。 これは次のように定義されます。
DECLARE_INTERFACE_(IDebugHost, IUnknown)
{
STDMETHOD(GetHostDefinedInterface)(_COM_Outptr_ IUnknown** hostUnk) PURE;
STDMETHOD(GetCurrentContext)(_COM_Outptr_ IDebugHostContext** context) PURE;
STDMETHOD(GetDefaultMetadata)(_COM_Outptr_ IKeyStore** defaultMetadataStore) PURE;
}
GetHostDefinedInterface の
GetHostDefinedInterface メソッドは、指定されたホストに対して存在する場合は、ホストのメイン プライベート インターフェイスを返します。 Windows 用デバッグ ツールの場合、ここで返されるインターフェイスは IDebugClient (IUnknown にキャスト) です。
GetCurrentContext の
GetCurrentContext メソッドは、デバッガー ホストの現在の状態を表すインターフェイスを返します。 この正確な意味はホストに委ねられますが、通常は、デバッグ ホストのユーザー インターフェイスでアクティブなセッション、プロセス、アドレス空間などが含まれます。 返されるコンテキスト オブジェクトは、呼び出し元に対してほとんど不透明ですが、デバッグ ホストへの呼び出し間で渡すことが重要なオブジェクトです。 呼び出し元がメモリを読み取る場合、メモリがどのプロセスとアドレス空間から読み取られているかを把握することが重要です。 この概念は、このメソッドから返されるコンテキスト オブジェクトの概念にカプセル化されます。
GetDefaultMetadata の
GetDefaultMetadata メソッドは、明示的なメタデータが渡されていない場合に特定の操作 (文字列変換など) に使用できる既定のメタデータ ストアを返します。 これにより、デバッグ ホストは、一部のデータの表示方法を制御できます。 たとえば、既定のメタデータには PreferredRadix キーを含めることができます。これにより、ホストは、序数を 10 進数で表示するか、16 進数で表示するかを指定できます (それ以外の場合)。
既定のメタデータ ストアのプロパティ値は手動で解決する必要があり、既定のメタデータのクエリ対象のオブジェクトを渡す必要があることに注意してください。 GetKeyValue の代わりに GetKey メソッドを使用する必要があります。
状態インターフェイスを する: IDebugHostStatus
IDebugHostStatus インターフェイスを使用すると、データ モデルまたはデバッグ ホストのクライアントは、デバッグ ホストの状態の特定の側面を照会できます。 インターフェイスは次のように定義されます。
DECLARE_INTERFACE_(IDebugHostStatus, IUnknown)
{
STDMETHOD(PollUserInterrupt)(_Out_ bool* interruptRequested) PURE;
}
PollUserInterrupt メソッドは、デバッグ ホストのユーザーが現在の操作の中断を要求したかどうかを確認するために使用されます。 たとえば、データ モデルのプロパティ アクセサーは、任意のコード (JavaScript メソッドなど) を呼び出す場合があります。 そのコードには、任意の時間がかかる場合があります。 デバッグ ホストの応答性を維持するために、任意の時間がかかる可能性があるそのようなコードでは、このメソッドを呼び出して割り込み要求を確認する必要があります。 interruptRequested 値が true として返された場合、呼び出し元はすぐに中止し、E_ABORTの結果を返す必要があります。
コンテキスト インターフェイスの : IDebugHostContext
コンテキストは、データ モデルと基になるデバッグ ホストの最も重要な側面の 1 つです。 オブジェクトを保持する場合は、オブジェクトがどこから来たのか(どのプロセスに含まれるか、どのアドレス空間に関連付けられているのか)を知ることができることが重要です。 この情報を知ることで、ポインター値などの正しい解釈が可能になります。 IDebugHostContext 型のオブジェクトは、デバッグ ホスト上の多くのメソッドに渡す必要があります。 このインターフェイスは、さまざまな方法で取得できます。
- デバッガーの現在のコンテキストを取得する: IDebugHost の GetCurrentContext メソッドを呼び出す
- オブジェクトのコンテキストを取得する: IModelObject の GetContext メソッドを呼び出す
- シンボルのコンテキストを取得する: IDebugHostSymbol の GetContext メソッドを呼び出す
さらに、データ モデルまたはデバッグ ホスト メソッドから返されるか、またはデータ モデルまたはデバッグ ホスト メソッドに渡される IDebugHostContext インターフェイスのコンテキストには、特別な意味を持つ 2 つの値があります。
nullptr: コンテキストがないことを示します。 一部のオブジェクトにコンテキストがない場合は、完全に有効です。 データ モデルのルート名前空間内の Debugger オブジェクトは、特定のプロセスまたはアドレス空間内の何も参照しません。 コンテキストがありません。
USE_CURRENT_HOST_CONTEXT: デバッグ ホストの現在の UI コンテキストを使用する必要があることを示すセンチネル値。 この値はデバッグ ホストから返されません。 ただし、IDebugHost の GetCurrentContext メソッドを明示的に呼び出す代わりに、入力 IDebugHostContext を受け取る任意のデバッグ ホスト メソッドに渡すことができます。 USE_CURRENT_HOST_CONTEXTを明示的に渡すことは、多くの場合、現在のコンテキストを明示的に取得するよりもパフォーマンスが高くなります。
ホスト コンテキストのコンテキストは、呼び出し元に対してほとんど不透明です。 コア デバッグ ホスト外の呼び出し元がホスト コンテキストで実行できる唯一の操作は、別のホスト コンテキストと比較することです。
IDebugHostContext インターフェイスは次のように定義されています。
DECLARE_INTERFACE_(IDebugHostContext, IUnknown)
{
STDMETHOD(IsEqualTo)(_In_ IDebugHostContext *pContext, _Out_ bool *pIsEqual) PURE;
}
IsEqualTo を
IsEqualTo メソッドは、ホスト コンテキストを別のホスト コンテキストと比較します。 2 つのコンテキストが等しい場合は、これが示されます。 この比較はインターフェイスの等価性ではないことに注意してください。 これにより、コンテキスト自体の基になる不透明な内容が比較されます。
エラー シンクを する: IDebugHostErrorSink
IDebugHostErrorSink は、クライアントが特定の操作中に発生したエラーの通知を受信し、必要に応じてそれらのエラーをルーティングする手段です。 インターフェイスは次のように定義されます。
enum ErrorClass
{
ErrorClassWarning,
ErrorClassError
}
DECLARE_INTERFACE_(IDebugHostErrorSink, IUnknown)
{
STDMETHOD(ReportError)(_In_ ErrorClass errClass, _In_ HRESULT hrError, _In_ PCWSTR message) PURE;
}
ReportError メソッドは、エラーが発生したことを通知し、シンクが適切な UI またはメカニズムにエラーをルーティングできるようにするための、エラー シンクのコールバックです。
ホスト エバリュエーターの : IDebugHostEvaluator / IDebugHostEvaluator2
デバッグ ホストがクライアントに提供する最も重要な機能の 1 つは、言語ベースの式エバリュエーターへのアクセスです。 IDebugHostEvaluator インターフェイスと IDebugHostEvaluator2 インターフェイスは、デバッグ ホストからその機能にアクセスするための手段です。
インターフェイスは次のように定義されます。
DECLARE_INTERFACE_(IDebugHostEvaluator2, IDebugHostEvaluator)
{
//
// IDebugHostEvaluator:
//
STDMETHOD(EvaluateExpression)(_In_ IDebugHostContext* context, _In_ PCWSTR expression, _In_opt_ IModelObject* bindingContext, _COM_Errorptr_ IModelObject** result, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
STDMETHOD(EvaluateExtendedExpression)(_In_ IDebugHostContext* context, _In_ PCWSTR expression, _In_opt_ IModelObject* bindingContext, _COM_Errorptr_ IModelObject** result, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
//
// IDebugHostEvaluator2:
//
STDMETHOD(AssignTo)(_In_ IModelObject* assignmentReference, _In_ IModelObject* assignmentValue, _COM_Errorptr_ IModelObject** assignmentResult, _COM_Outptr_opt_result_maybenull_ IKeyStore** assignmentMetadata) PURE;
}
EvaluateExpression の
EvaluateExpression メソッドを使用すると、デバッグ ホストに言語 (C++など) 式を評価し、IModelObject としてボックス化された式評価の結果の値を返すように要求できます。 このメソッドの特定のバリアントでは、言語コンストラクトのみが許可されます。 言語 (LINQ クエリ メソッドなど) に存在しないデバッグ ホストの式エバリュエーター内に表示される追加機能は、評価のためにオフになります。
EvaluateExtendedExpression の
EvaluateExtendedExpression メソッドは EvaluateExpression メソッドに似ていますが、特定のデバッグ ホストが式エバリュエーターに追加することを選択した言語以外の追加機能に戻る点が異なります。 たとえば、Windows 用のデバッグ ツールでは、匿名型、LINQ クエリ、モジュール修飾子、書式指定子、およびその他の C/C++ 以外の機能が有効になります。
IDebugHostEvaluator2 の
AssignTo の
AssignTo メソッドは、デバッグする言語のセマンティクスに従って割り当てを実行します。
ホスト拡張インターフェイスの : IDebugHostExtensibility
デバッグ ホストの特定の機能は、必要に応じて拡張性の対象となります。 たとえば、式エバリュエーターを含めることができます。 IDebugHostExtensibility インターフェイスは、これらの拡張ポイントにアクセスするための手段です。 インターフェイスは次のように定義されます。
DECLARE_INTERFACE_(IDebugHostExtensibility, IUnknown)
{
STDMETHOD(CreateFunctionAlias)(_In_ PCWSTR aliasName, _In_ IModelObject *functionObject) PURE;
STDMETHOD(DestroyFunctionAlias)(_In_ PCWSTR aliasName) PURE;
}
CreateFunctionAlias の
CreateFunctionAlias メソッドは、一部の拡張機能で実装されるメソッドの "クイック エイリアス" である "関数エイリアス" を作成します。 このエイリアスの意味はホスト固有です。 関数を使用してホストの式エバリュエーターを拡張したり、まったく異なる処理を行ったりすることがあります。
DestroyFunctionAlias メソッドは、CreateFunctionAlias メソッドの以前の呼び出しを元に戻します。 この関数は、クイック エイリアス名では使用できなくなります。
データ モデルへのアクセスの
まず第一に、データ モデル拡張 API は、データ モデルのホストとして機能するアプリケーション (通常はデバッガー) に中立的に設計されています。 理論上、どのアプリケーションでも、アプリケーションのデバッグ ターゲットの型システムを公開する一連のホスト API と、投影されたオブジェクトのセットをデータ モデルの名前空間に公開し、ターゲット、プロセス、スレッドなどを提供することで、データ モデルをホストできます。は、これらのデバッグ ターゲットにあります。
データ モデル API (IDataModel、IDebugHost、IModelObject のオフシュート) は移植可能に設計されていますが、"デバッガー拡張機能" とは何かを定義しません。 現在、Debugging Tools for Windows とそのエンジンを拡張するコンポーネントは、データ モデルにアクセスするためにエンジン拡張機能を記述する必要があります。 そのエンジン拡張機能は、拡張機能の読み込みとブートストラップ のメカニズムと同程度のエンジン拡張機能である必要があります。 そのため、最小限の実装では次の内容が提供されます。
- DebugExtensionInitialize: 作成された IDebugClient を利用してデータ モデルにアクセスし、オブジェクト モデル操作を設定するメソッド。
- DebugExtensionUninitialize: DebugExtensionInitialize で実行されたオブジェクト モデル操作を元に戻すメソッド。
- DebugExtensionCanUnload: 拡張機能がアンロードできるかどうかを返すメソッド。 拡張機能にまだライブ COM オブジェクトがある場合は、これを示す必要があります。 これは、COM の DllCanUnloadNow に相当するデバッガーです。 これがアンロードできないことを示すS_FALSEを返す場合、デバッガーは後でこれを照会して、アンロードが安全かどうかを確認するか、DebugExtensionInitialize をもう一度呼び出して拡張機能を再初期化できます。 両方のパスを処理するには、拡張機能を準備する必要があります。
- DebugExtensionUnload: DLL がアンロードされる直前に必要な最終的なクリーンアップを実行するメソッド
ブリッジ インターフェイスの : IHostDataModelAccess
前述のように、DebugExtensionInitialize が呼び出されると、デバッグ クライアントが作成され、データ モデルにアクセスできるようになります。 このようなアクセスは、Debugging Tools for Windows のレガシ IDebug* インターフェイスとデータ モデルの間のブリッジ インターフェイスによって提供されます。 このブリッジ インターフェイスは "IHostDataModelAccess" であり、次のように定義されています。
DECLARE_INTERFACE_(IHostDataModelAccess, IUnknown)
{
STDMETHOD(GetDataModel)(_COM_Outptr_ IDataModelManager** manager, _COM_Outptr_ IDebugHost** host) PURE;
}
GetDataModel の
GetDataModel メソッドは、データ モデルの両側へのアクセスを提供するブリッジ インターフェイス上のメソッドです。デバッグ ホスト (デバッガーの下端) は、返された IDebugHost インターフェイスによって表されます。データ モデルのメイン コンポーネントは、返された IDataModelManager インターフェイスによって表されます。
デバッガー データ モデル システム インターフェイス
データ モデル ホスト を する
デバッガー データ モデルは、さまざまなコンテキストでホストできるコンポーネント化されたシステムとして設計されています。 通常、データ モデルはデバッガー アプリケーションのコンテキストでホストされます。 データ モデルのホストにするには、デバッガーの主要な側面 (ターゲット設定、メモリ空間、エバリュエーター、シンボリック システム、型システムなど) を公開するために、多くのインターフェイスを実装する必要があります。これらのインターフェイスは、データ モデルをホストする任意のアプリケーションによって実装されますが、コア データ モデルと、データ モデルと相互運用する拡張機能の両方によって使用されます。
型システムインターフェイスとシンボリック インターフェイスは次のとおりです。
| インターフェイス名 | 説明 |
|---|---|
| IDebugHostSymbols | シンボルへのアクセスと解決を提供するコア インターフェイス |
| IDebugHostSymbol / IDebugHostSymbol2 | 任意の種類の 1 つのシンボルを表します。 特定のシンボルは、このインターフェイスの派生です。 |
| IDebugHostModule | プロセス内で読み込まれたモジュールを表します。 これは一種のシンボルです。 |
| IDebugHostType / IDebugHostType2 | ネイティブ/言語型を表します。 |
| IDebugHostConstant | シンボリック情報内の定数を表します (C++ の型以外のテンプレート引数など)。 |
| IDebugHostField | 構造体またはクラス内のフィールドを表します。 |
| IDebugHostData | モジュール内のデータを表します (構造体またはクラス内では IDebugHostField になります) |
| IDebugHostBaseClass | 基底クラスを表します。 |
| IDebugHostPublic | PDB の publics テーブル内のシンボルを表します。 これには型情報が関連付けされていません。 名前とアドレスです。 |
| IDebugHostModuleSignature | モジュールシグネチャを表します。名前またはバージョンによってモジュールのセットと一致する定義です。 |
| IDebugHostTypeSignature | 型シグネチャを表します。モジュールや名前によって一連の型と一致する定義です。 |
その他のコア インターフェイスは次のとおりです。
| インターフェイス名 | 説明 |
|---|---|
| IDebugHost | デバッグ ホストへのコア インターフェイス。 |
| IDebugHostStatus | クライアントがホストの状態を照会できるようにするインターフェイス。 |
| IDebugHostContext | ホスト内のコンテキストの抽象化 (たとえば、特定のターゲット、特定のプロセス、特定のアドレス空間など)。 |
| IDebugHostErrorSink | ホストとデータ モデルの特定の部分からエラーを受信するために呼び出し元によって実装されるインターフェイス |
| IDebugHostEvaluator / IDebugHostEvaluator2 | デバッグ ホストの式エバリュエーター。 |
| IDebugHostExtensibility | ホストまたはホストの一部 (式エバリュエーターなど) の機能を拡張するためのインターフェイス。 |
メイン シンボリック インターフェイスの : IDebugHostSymbols
IDebugHostSymbols インターフェイスは、デバッグ ターゲット内のシンボルにアクセスするための主要な開始点です。 このインターフェイスは IDebugHost のインスタンスから照会でき、次のように定義されます。
DECLARE_INTERFACE_(IDebugHostSymbols, IUnknown)
{
STDMETHOD(CreateModuleSignature)(_In_z_ PCWSTR pwszModuleName, _In_opt_z_ PCWSTR pwszMinVersion, _In_opt_z_ PCWSTR pwszMaxVersion, _Out_ IDebugHostModuleSignature** ppModuleSignature) PURE;
STDMETHOD(CreateTypeSignature)(_In_z_ PCWSTR signatureSpecification, _In_opt_ IDebugHostModule* module, _Out_ IDebugHostTypeSignature** typeSignature) PURE;
STDMETHOD(CreateTypeSignatureForModuleRange)(_In_z_ PCWSTR signatureSpecification, _In_z_ PCWSTR moduleName, _In_opt_z_ PCWSTR minVersion, _In_opt_z_ PCWSTR maxVersion, _Out_ IDebugHostTypeSignature** typeSignature) PURE;
STDMETHOD(EnumerateModules)(_In_ IDebugHostContext* context, _COM_Outptr_ IDebugHostSymbolEnumerator** moduleEnum) PURE;
STDMETHOD(FindModuleByName)(_In_ IDebugHostContext* context, _In_z_ PCWSTR moduleName, _COM_Outptr_ IDebugHostModule **module) PURE;
STDMETHOD(FindModuleByLocation)(_In_ IDebugHostContext* context, _In_ Location moduleLocation, _COM_Outptr_ IDebugHostModule **module) PURE;
STDMETHOD(GetMostDerivedObject)(_In_opt_ IDebugHostContext *pContext, _In_ Location location, _In_ IDebugHostType* objectType, _Out_ Location* derivedLocation, _Out_ IDebugHostType** derivedType) PURE;
}
CreateModuleSignature の
CreateModuleSignature メソッドはシグネチャを作成します。このシグネチャを使用して、名前とオプションでバージョン別に特定のモジュールのセットを照合できます。 モジュール署名には、次の 3 つのコンポーネントがあります。
- 名前: 一致するモジュールには、シグネチャ内の名前と完全に大文字と小文字が区別されない一致する名前が必要です
- 最小バージョン: 指定した場合、一致するモジュールには、少なくともこのバージョンと同じ高さである最小バージョンが必要です。 バージョンは "A.B.C.D" 形式で指定され、それ以降の各部分の重要度は以前よりも低くなります。 最初のセグメントのみが必須です。
- 最大バージョン: 指定した場合、一致するモジュールには、このバージョン以下の最大バージョンが必要です。 バージョンは "A.B.C.D" 形式で指定され、それ以降の各部分の重要度は以前よりも低くなります。 最初のセグメントのみが必須です。
CreateTypeSignature の
CreateTypeSignature メソッドは、モジュールと型名を含めることで、具象型のセットとの照合に使用できるシグネチャを作成します。 型名シグネチャ文字列の形式は、デバッグ対象の言語 (およびデバッグ ホスト) に固有です。 C/C++ の場合、シグネチャ文字列は NatVis 型仕様と同じです。 つまり、シグネチャ文字列は、テンプレート引数にワイルドカード (*として指定) を使用できる型名です。
CreateTypeSignatureForModuleRange の
CreateTypeSignatureForModuleRange メソッドは、モジュールシグネチャと型名によって具象型のセットを照合するために使用できるシグネチャを作成します。 これは CreateTypeSignature メソッドに似ていますが、シグネチャに一致する特定のモジュールを渡す代わりに、呼び出し元はモジュールシグネチャを作成するために必要な引数を渡します (モジュールシグネチャが CreateModuleSignature メソッドで作成されたかのように)。
EnumerateModules メソッドは、特定のホスト コンテキストで使用可能なすべてのモジュールを列挙する列挙子を作成します。 そのホスト コンテキストは、プロセス コンテキストをカプセル化するか、Windows カーネルのようなものをカプセル化する可能性があります。
FindModuleByName の
FindModuleByName メソッドは、指定されたホスト コンテキストを調べるし、指定した名前を持つモジュールを検索し、それにインターフェイスを返します。 ファイル拡張子の有無にかかわらず、名前でモジュールを検索することは有効です。
FindModuleByLocation の
FindModuleByLocation メソッドは、指定されたホスト コンテキストを調べて、指定された場所によって指定されたアドレスが含まれているモジュールを決定します。 その後、そのようなモジュールにインターフェイスが返されます。
GetMostDerivedObject の
GetMostDerivedObject は、デバッガーの型システムを使用して、静的な型からオブジェクトのランタイム型を決定します。 このメソッドは、この分析を実行するために、タイプ システム レイヤーで使用可能なシンボリック情報とヒューリスティックのみを使用します。 このような情報には、C++ RTTI (実行時の型情報) や、オブジェクトの仮想関数テーブルの形状の分析が含まれる場合があります。 IModelObject で推奨されるランタイム型の概念などは含まれません。 分析でランタイム型が見つからない場合、またはメソッドに渡された静的型とは異なるランタイム型が見つからない場合は、入力の場所と型が渡される可能性があります。これらの理由から、メソッドは失敗しません。
コア個別シンボル インターフェイスの : IDebugHostSymbol
データ モデル ホストから返すことができるすべてのシンボルは、IDebugHostSymbol から何らかの方法で派生します。 これは、シンボルの種類に関係なく、すべてのシンボルが実装するコア インターフェイスです。 シンボルの種類に応じて、特定のシンボルは、このインターフェイスによって表される特定の種類のシンボルに固有の属性を返す他のインターフェイスのセットを実装できます。 IDebugHostSymbol2 / IDebugHostSymbol インターフェイスは次のように定義されています。
DECLARE_INTERFACE_(IDebugHostSymbol2, IDebugHostSymbol)
{
//
// IDebugHostSymbol:
//
STDMETHOD(GetContext)(_COM_Outptr_ IDebugHostContext** context) PURE;
STDMETHOD(EnumerateChildren)(_In_ SymbolKind kind, _In_opt_z_ PCWSTR name, _Out_ IDebugHostSymbolEnumerator **ppEnum) PURE;
STDMETHOD(GetSymbolKind)(_Out_ SymbolKind *kind) PURE;
STDMETHOD(GetName)(_Out_ BSTR* symbolName) PURE;
STDMETHOD(GetType)(_Out_ IDebugHostType** type) PURE;
STDMETHOD(GetContainingModule)(_Out_ IDebugHostModule **containingModule) PURE;
STDMETHOD(CompareAgainst)(_In_ IDebugHostSymbol *pComparisonSymbol, _In_ ULONG comparisonFlags, _Out_ bool *pMatches) PURE;
//
// IDebugHostSymbol2
//
STDMETHOD(EnumerateChildrenEx)(_In_ SymbolKind kind, _In_opt_z_ PCWSTR name, _In_opt_ SymbolSearchInfo* searchInfo, _Out_ IDebugHostSymbolEnumerator **ppEnum) PURE;
}
このインターフェイスは、次のような値を持つ SymbolKind 列挙体によって示される、さまざまな種類のシンボルを表す点に注意することが非常に重要です。
| Enumarant | 意味 |
|---|---|
| 記号 | 指定されていないシンボルの種類 |
| SymbolModule | シンボルはモジュールであり、IDebugHostModule に対してクエリを実行できます |
| SymbolType | シンボルは型であり、IDebugHostType に対してクエリを実行できます |
| SymbolField | シンボルはフィールド (構造体またはクラス内のデータ メンバー) であり、IDebugHostField に対してクエリを実行できます |
| SymbolConstant | シンボルは定数値であり、IDebugHostConstant に対してクエリを実行できます |
| SymbolData | シンボルは、構造体またはクラスのメンバーではなく、IDebugHostData に対してクエリ可能なデータです。 |
| SymbolBaseClass | シンボルは基底クラスであり、IDebugHostBaseClass に対してクエリ可能です |
| SymbolPublic | シンボルはモジュールの publics テーブル内のエントリであり (型情報がありません)、IDebugHostPublic に対してクエリを実行できます。 |
| SymbolFunction | シンボルは関数であり、IDebugHostData に対してクエリ可能です |
GetContext の
GetContext メソッドは、シンボルが有効なコンテキストを返します。 これはデバッグ ターゲットやシンボルが存在するプロセス/アドレス空間などを表しますが、他の方法 (たとえば、IModelObjectから) 取得されたコンテキストほど具体的でない場合があります。
EnumerateChildren の
EnumerateChildren メソッドは、指定されたシンボルのすべての子を列挙する列挙子を返します。 たとえば、C++ 型の場合、基底クラス、フィールド、メンバー関数などはすべて、型シンボルの子と見なされます。
モジュール インターフェイスの : IDebugHostModule
一部のアドレス空間内に読み込まれるモジュールのデバッガーの概念は、データ モデルの 2 つの異なる方法で表されます。IDebugHostModule インターフェイスを介した型システム レベルで表されます。 ここで、モジュールはシンボルであり、モジュールのコア属性は、Debugger.Models.Module データ モデルを介してデータ モデル レベルで射射されるインターフェイス メソッド呼び出しです。 これは、モジュールの型システム IDebugHostModule 表現の拡張可能なカプセル化です。
IDebugHostModule インターフェイスは次のように定義されます (IDebugHostSymbol にジェネリックなメソッドは無視されます)。
DECLARE_INTERFACE_(IDebugHostModule, IDebugHostSymbol)
{
//
// IDebugHostModule:
//
STDMETHOD(GetImageName)(_In_ bool allowPath, _Out_ BSTR* imageName) PURE;
STDMETHOD(GetBaseLocation)(_Out_ Location* moduleBaseLocation) PURE;
STDMETHOD(GetVersion)(_Out_opt_ ULONG64* fileVersion, _Out_opt_ ULONG64* productVersion) PURE;
STDMETHOD(FindTypeByName)(_In_z_ PCWSTR typeName, _Out_ IDebugHostType** type) PURE;
STDMETHOD(FindSymbolByRVA)(_In_ ULONG64 rva, _Out_ IDebugHostSymbol** symbol) PURE;
STDMETHOD(FindSymbolByName)(_In_z_ PCWSTR symbolName, _Out_ IDebugHostSymbol** symbol) PURE;
}
GetImageName を
GetImageName メソッドは、モジュールのイメージ名を返します。 allowPath 引数の値によっては、返されるイメージ名にイメージへの完全なパスが含まれている場合と含まれていない場合があります。
GetBaseLocation の
GetBaseLocation メソッドは、モジュールのベース ロード アドレスを場所構造として返します。 モジュールの返される場所の構造は、通常、仮想アドレスを参照します。
GetVersion メソッドは、モジュールに関するバージョン情報を返します (このような情報をヘッダーから正常に読み取ることができると仮定します)。 特定のバージョンが (nullptr 以外の出力ポインターを介して) 要求され、読み取ることができない場合は、メソッド呼び出しから適切なエラー コードが返されます。
FindTypeByName メソッドは、モジュール内で定義されている型を型名で検索し、その型シンボルを返します。 このメソッドは、モジュールの子の明示的な再帰によって返されない有効な IDebugHostType を返す場合があります。 デバッグ ホストでは、派生型 (モジュール自体内では使用されず、派生型から派生した型) を作成できる場合があります。 たとえば、MyStruct 構造体がモジュールのシンボルで定義されているが、MyStruct ** 型が使用されない場合、FindTypeByName メソッドは、その型名がモジュールのシンボルに明示的に表示されないにもかかわらず、MyStruct ** の型シンボルを正当に返す可能性があります。
FindSymbolByRVA の
FindSymbolByRVA メソッドは、モジュール内の指定された相対仮想アドレスで一致する 1 つのシンボルを検索します。 指定された RVA に 1 つのシンボルがない場合 (例: 複数の一致がある場合)、このメソッドによってエラーが返されます。 このメソッドは、publics テーブル内のシンボルよりもプライベート シンボルを返す方が優先されることに注意してください。
FindSymbolByName の
FindSymbolByName メソッドは、モジュール内の指定された名前の 1 つのグローバル シンボルを検索します。 指定された名前と一致するシンボルが 1 つも存在しない場合、このメソッドによってエラーが返されます。 このメソッドは、publics テーブル内のシンボルよりもプライベート シンボルを返す方が優先されることに注意してください。
型システムへのアクセスの : IDebugHostType2 / IDebugHostType
特定の言語/ネイティブ型は、IDebugHostType2 インターフェイスまたは IDebugHostType インターフェイスによって記述されます。 これらのインターフェイスの一部のメソッドは、特定の種類の型にのみ適用されることに注意してください。 特定の型シンボルは、TypeKind 列挙型で説明されているように、次のいずれかの型を参照できます。
| 型の種類 | 説明 |
|---|---|
| TypeUDT | ユーザー定義型 (構造体、クラス、共用体など)。型が TypeUDT であるネイティブ型を持つモデル オブジェクトは ObjectTargetObject の正規表現を持ち、その型は常に対応する IModelObject 内に保持されます。 |
| TypePointer | ポインター。 型が TypePointer であるネイティブ型を持つモデル オブジェクトは ObjectIntrinsic の正規表現を持ち、ポインターの値は 0 でVT_UI8に拡張され、この 64 ビット形式で組み込みデータとして保持されます。 TypePointer のすべての型シンボルには、ポインターが指す型の基本型 (GetBaseType メソッドによって返される) があります。 |
| TypeMemberPointer | クラス メンバーへのポインター。 型が TypeMemberPointer であるネイティブ型を持つモデル オブジェクトは、組み込みの正規表現 (ポインター値と同じ値) を持ちます。 この値の正確な意味は、コンパイラ/デバッグ ホスト固有です。 |
| TypeArray | 配列。 種類が TypeArray であるネイティブ型を持つモデル オブジェクトは、ObjectTargetObject の正規表現を持ちます。 配列のベース アドレスはオブジェクトの位置 (GetLocation メソッドを使用して取得) であり、配列の型は常に保持されます。 TypeArray のすべての型シンボルには、配列が配列である型の基本型 (GetBaseType メソッドによって返されます) があります。 |
| TypeFunction | 関数。 |
| TypeTypedef | typedef。 型が TypeTypedef であるネイティブ型を持つモデル オブジェクトは、typedef の基になる最終的な型の正規表現と同じ正規表現を持ちます。 これは、IDebugHostType2 の明示的な typedef メソッドを使用して typedef 情報を照会したり、typedef に対して明示的なデータ モデルが登録されていない限り、オブジェクトのエンド ユーザーと型情報に対して完全に透過的に表示されます。 GetTypeKind メソッドは TypeTypedef を返しません。 すべてのメソッドは、typedef の基になる最終的な型が返す内容を返します。 IDebugHostType2 には typedef 固有のメソッドがあり、これを使用して typedef 固有の情報を取得できます。 |
| TypeEnum | 列挙型。 型が TypeEnum であるネイティブ型を持つモデル オブジェクトは ObjectIntrinsic の正規表現を持ち、組み込みの値と型は列挙型の値と同じです。 |
| TypeIntrinsic | 組み込み (基本型)。 型が TypeIntrinsic であるネイティブ型を持つモデル オブジェクトは、ObjectIntrinsic の正規表現を持ちます。 型情報は保持される場合と保持されない場合があります。特に、基になる型が IModelObject に格納されている組み込みデータのバリアント データ型 (VT_*) によって完全に記述されている場合 |
IDebugHostType2/IDebugHostType インターフェイス全体は、次のように定義されます (IDebugHostSymbol メソッドを除く)。
DECLARE_INTERFACE_(IDebugHostType2, IDebugHostType)
{
//
// IDebugHostType:
//
STDMETHOD(GetTypeKind)(_Out_ TypeKind *kind) PURE;
STDMETHOD(GetSize)(_Out_ ULONG64* size) PURE;
STDMETHOD(GetBaseType)(_Out_ IDebugHostType** baseType) PURE;
STDMETHOD(GetHashCode)(_Out_ ULONG* hashCode) PURE;
STDMETHOD(GetIntrinsicType)(_Out_opt_ IntrinsicKind *intrinsicKind, _Out_opt_ VARTYPE *carrierType) PURE;
STDMETHOD(GetBitField)(_Out_ ULONG* lsbOfField, _Out_ ULONG* lengthOfField) PURE;
STDMETHOD(GetPointerKind)(_Out_ PointerKind* pointerKind) PURE;
STDMETHOD(GetMemberType)(_Out_ IDebugHostType** memberType) PURE;
STDMETHOD(CreatePointerTo)(_In_ PointerKind kind, _COM_Outptr_ IDebugHostType** newType) PURE;
STDMETHOD(GetArrayDimensionality)(_Out_ ULONG64* arrayDimensionality) PURE;
STDMETHOD(GetArrayDimensions)(_In_ ULONG64 dimensions, _Out_writes_(dimensions) ArrayDimension *pDimensions) PURE;
STDMETHOD(CreateArrayOf)(_In_ ULONG64 dimensions, _In_reads_(dimensions) ArrayDimension *pDimensions, _COM_Outptr_ IDebugHostType** newType) PURE;
STDMETHOD(GetFunctionCallingConvention)(_Out_ CallingConventionKind* conventionKind) PURE;
STDMETHOD(GetFunctionReturnType)(_COM_Outptr_ IDebugHostType** returnType) PURE;
STDMETHOD(GetFunctionParameterTypeCount)(_Out_ ULONG64* count) PURE;
STDMETHOD(GetFunctionParameterTypeAt)(_In_ ULONG64 i, _Out_ IDebugHostType** parameterType) PURE;
STDMETHOD(IsGeneric)(_Out_ bool* isGeneric) PURE;
STDMETHOD(GetGenericArgumentCount)(_Out_ ULONG64* argCount) PURE;
STDMETHOD(GetGenericArgumentAt)(_In_ ULONG64 i, _Out_ IDebugHostSymbol** argument) PURE;
//
// IDebugHostType2:
//
STDMETHOD(IsTypedef)(_Out_ bool* isTypedef) PURE;
STDMETHOD(GetTypedefBaseType)(_Out_ IDebugHostType2** baseType) PURE;
STDMETHOD(GetTypedefFinalBaseType)(_Out_ IDebugHostType2** finalBaseType) PURE;
STDMETHOD(GetFunctionVarArgsKind)(_Out_ VarArgsKind* varArgsKind) PURE;
}
IDebugHostType2/IDebugHostType General メソッド
次の IDebugHostType メソッドは、GetTypeKind メソッドから返される種類に関係なく、あらゆる型に対して一般的です。
STDMETHOD(GetTypeKind)(_Out_ TypeKind *kind) PURE;
STDMETHOD(GetSize)(_Out_ ULONG64* size) PURE;
STDMETHOD(GetBaseType)(_Out_ IDebugHostType** baseType) PURE;
STDMETHOD(GetHashCode)(_Out_ ULONG* hashCode) PURE;
GetTypeKind の
GetTypeKind メソッドは、シンボルが参照する型 (ポインター、配列、組み込みなど) の種類を返します。
GetSize メソッドは、型のサイズを返します (C++ で sizeof(type) を実行したかのように)。
GetBaseType の
型が別の単一型の派生型である場合 (MyStruct * が MyStruct から派生した場合など)、GetBaseType メソッドは派生の基本型を返します。 ポインターの場合、これは指す型を返します。 配列の場合、配列が配列であるものを返します。 型がそのような派生型でない場合は、エラーが返されます。
GetHashCode を する
GetHashCode メソッドは、型の 32 ビット ハッシュ コードを返します。 グローバル一致 (たとえば、ホストで許可されている場合はすべてに一致する * に相当する型シグネチャ) を除き、特定の型シグネチャと一致できる型インスタンスは、同じハッシュ コードを返す必要があります。 このメソッドは、型シグネチャを型のインスタンスと照合するために、型シグネチャと組み合わせて使用されます。
IDebugHostType2/IDebugHostType 組み込みメソッド
次の IDebugHostType メソッドは、組み込み型 (または列挙型などの組み込みデータを保持する型) に固有です。
STDMETHOD(GetIntrinsicType)(_Out_opt_ IntrinsicKind *intrinsicKind, _Out_opt_ VARTYPE *carrierType) PURE;
GetIntrinsicType の
GetIntrinsicType メソッドは、型の組み込みの種類に関する情報を返します。 このメソッドから 2 つの値が返されます。
- 組み込み型は、型全体 (整数、符号なし、浮動小数点など) を示しますが、型のサイズ (例: 8 ビット、16 ビット、32 ビット、64 ビット) を示します。
- キャリア型は、組み込みの種類が VARIANT 構造体にどのようにパックされるかを示します。 これはVT_* 定数です。
2 つの値の組み合わせによって、組み込み関数に関する情報の完全なセットが提供されます。
IDebugHostType2/IDebugHostType Bitfield メソッド
次の IDebugHostType メソッドは、ビットフィールドにデータを格納する型に固有です。 組み込み内のビットフィールド配置に関する情報は、場所の属性ではなく、データ モデルの型シンボルの一部として格納されます。
STDMETHOD(GetBitField)(_Out_ ULONG* lsbOfField, _Out_ ULONG* lengthOfField) PURE;
GetBitField を
データ構造の特定のメンバーがビットフィールド (ULONG MyBits:8 など) の場合、フィールドの型情報にはビットフィールドの配置に関する情報が含まれます。 GetBitField メソッドを使用して、その情報を取得できます。 このメソッドは、ビットフィールドではない任意の型で失敗します。 これが、メソッドが失敗する唯一の理由です。 このメソッドを呼び出し、成功/失敗を調べることで、ビット フィールドとビット以外のフィールドを区別するだけで十分です。 特定の型がビットフィールドの場合、フィールドの位置は、半開きセット (lsbOfField + lengthOfField : lsbOfField] によって定義されます
IDebugHostType2/IDebugHostType ポインター関連のメソッド
次の IDebugHostType メソッドはポインター型に固有です。 GetTypeKind が TypePointer または TypeMemberPointer を返す型は次のとおりです。
STDMETHOD(GetPointerKind)(_Out_ PointerKind* pointerKind) PURE;
STDMETHOD(GetMemberType)(_Out_ IDebugHostType** memberType) PURE;
GetPointerKind の
ポインターである型の場合、GetPointerKind メソッドはポインターの種類を返します。 これは PointerKind 列挙型によって定義されます。
メンバーへのポインターである型 (TypeMemberPointer の型の種類で示されます) の場合、GetMemberType メソッドは、ポインターがメンバーへのポインターであるクラスを返します。
IDebugHostType2/IDebugHostType 配列関連のメソッド
配列は、GetTypeKind が TypeArray を返す型です。 デバッグ ホストの型システムで定義されている配列は、C が利用する 1 次元のゼロ インデックス ベースのパックされた線形 1 次元配列と同じではないことに注意してください。 C スタイルの配列は定義に適合しますが、配列の全体的なスコープは IDebugHostType の方が広いです。 デバッグ ホスト内の配列は多次元にすることができ、配列内の各次元は ArrayDimension と呼ばれる記述子によって定義されます。この記述子には次のフィールドがあります。
| フィールド | 意味 |
|---|---|
| LowerBound | 符号付き 64 ビット値としての配列の基本インデックス。 C スタイル配列の場合、これは常に 0 になります。 する必要はありません。 配列の個々の次元は、負のインデックスであっても、任意の 64 ビット インデックスから開始すると見なすことができます。 |
| 長さ | 符号なし 64 ビット値としての配列次元の長さ。 配列の内容は、半開きセット [LowerBound, LowerBound + Length] にまたがっています。 |
| 歩幅 | 配列ディメンションのストライドを定義します。 このディメンションのインデックスで 1 を (N から N + 1 に) 増やすと、メモリ内で進むバイト数が示されます。 C スタイル配列の場合、これは配列の各要素のサイズになります。 である必要はありません。 要素間のパディングは、各要素のサイズより大きいストライドとして表すことができます。 多次元配列の場合、この値は次元全体を前方に移動する方法を示します。 M x N 行列を考えてみましょう。 これは、行メジャー形式で 2 つのディメンションとして記述される場合があります。 |
{ [LowerBound: 0, Length: M, Stride: N \* sizeof(element)], [LowerBound: 0, Length: N, Stride: sizeof(element)]}
または、列メジャー形式で 2 つのディメンションとして記述することもできます。
{ [LowerBound: 0, Length: M, Stride: sizeof(element)], [LowerBound: 0, Length: N, Stride: M \* sizeof(element)]}
ArrayDimension の概念により、この程度の柔軟性が実現します。
次の IDebugHostType メソッドは配列型に固有です。
STDMETHOD(GetArrayDimensionality)(\_Out_ ULONG64\* arrayDimensionality) PURE;
STDMETHOD(GetArrayDimensions)(\_In_ ULONG64 dimensions, \_Out_writes_(dimensions) ArrayDimension \*pDimensions) PURE;
GetArrayDimensionality メソッドは、配列のインデックスが作成される次元の数を返します。 C スタイルの配列の場合、ここで返される値は常に 1 になります。
GetArrayDimensions を
GetArrayDimensions メソッドは、GetArrayDimensionality メソッドによって示される配列の次元ごとに 1 つずつ、記述子のセットを返します。 各記述子は ArrayDimension 構造体であり、各配列ディメンションの開始インデックス、長さ、および前方ストライドを記述します。 これにより、C 型システムで許可されているよりもはるかに強力な配列コンストラクトの説明が可能になります。
C スタイルの配列の場合、ここでは常に次の値を持つ 1 つの配列ディメンションが返されます。
- LowerBound = 0
- Length = ARRAYSIZE(array)
- Stride = sizeof(elementType)
IDebugHostType2/IDebugHostType 関数関連のメソッド
TypeFunction の種類を介して関数型であることを示す型は、IDebugHostType と IDebugHostType2 の両方で次のメソッドをサポートします。
//
// IDebugHostType:
//
STDMETHOD(GetFunctionCallingConvention)(_Out_ CallingConventionKind* conventionKind) PURE;
STDMETHOD(GetFunctionReturnType)(_COM_Outptr_ IDebugHostType** returnType) PURE;
STDMETHOD(GetFunctionParameterTypeCount)(_Out_ ULONG64* count) PURE;
STDMETHOD(GetFunctionParameterTypeAt)(_In_ ULONG64 i, _Out_ IDebugHostType** parameterType) PURE;
//
// IDebugHostType2:
//
STDMETHOD(GetFunctionVarArgsKind)(_Out_ VarArgsKind* varArgsKind) PURE;
GetFunctionCallingConvention の
GetFunctionCallingConvention メソッドは、関数の呼び出し規則を返します。 このような値は、CallingConventionKind 列挙体のメンバーとして返されます。
GetFunctionReturnType を
GetFunctionReturnType メソッドは、関数の戻り値の型を返します。
GetFunctionParameterTypeCount の
GetFunctionParameterTypeCount メソッドは、関数が受け取る引数の数を返します。 この数では、C/C++ の省略記号ベースの変数引数マーカーは考慮されないことに注意してください。 このような存在は、GetFunctionVarArgsKind メソッドを使用して検出する必要があります。 これには、省略記号の前の引数のみが含まれます。
GetFunctionParameterTypeAt を
GetFunctionParameterTypeAt メソッドは、i 番目の引数の型を関数に返します。
GetFunctionVarArgsKind メソッドは、特定の関数が変数引数リストを使用するかどうかを返します。その場合は、変数引数のスタイルを使用します。 このような定義は、次のように定義された VarArgsKind 列挙体のメンバーによって定義されます。
| Enumerant | 意味 |
|---|---|
| VarArgsNone | この関数は変数引数を受け取りません。 |
| VarArgsCStyle | この関数は C スタイルの varargs 関数 (returnType(arg1, arg2, ...)) です。関数によって報告される引数の数には、省略記号引数は含まれません。 変数引数の受け渡しは、GetFunctionParameterTypeCount メソッドによって返される引数の数の後に発生します。 |
IDebugHostType2 GetFunctionVarArgsKind
GetFunctionVarArgsKind メソッドは、特定の関数が変数引数リストを使用するかどうかを返します。その場合は、変数引数のスタイルを使用します。 このような定義は、次のように定義された VarArgsKind 列挙体のメンバーによって定義されます。
IDebugHostType2/IDebugHostType Typedef 関連メソッド
typedef である型は、型が typedef の基になる最終的な型であるかのように動作します。 つまり、GetTypeKind などのメソッドは、型が typedef であることを示しません。 同様に、GetBaseType は定義が参照する型を返しません。 代わりに、typedef の基になる最終的な定義で呼び出されたかのように動作することを示します。 例
typedef MYSTRUCT *PMYSTRUCT;
typedef PMYSTRUCT PTRMYSTRUCT;
"PMYSTRUCT" または "PTRMYSTRUCT" の IDebugHostType は、次の情報を報告します。
- GetTypeKind メソッドは TypePointer を返します。 最終的な基になる型 MYSTRUCT * は、実際にはポインターです。
- 'GetBaseType メソッドは、MYSTRUCT の型を返します。 MYSTRUCT * の基になる型は MYSTRUCT です。
ここでの唯一の違いは、IDebugHostType2 の typedef 固有のメソッドの動作です。 これらのメソッドは次のとおりです。
STDMETHOD(IsTypedef)(_Out_ bool* isTypedef) PURE;
STDMETHOD(GetTypedefBaseType)(_Out_ IDebugHostType2** baseType) PURE;
STDMETHOD(GetTypedefFinalBaseType)(_Out_ IDebugHostType2** finalBaseType) PURE;
この例では、次の操作を行います。
- ISTypedef メソッドは、PMYSTRUCT と PTRMYSTRUCT の両方に対して true を返します
- GetTypedefBaseType メソッドは、PMYSTRUCT の場合は MYSTRUCT * を、PTRMYSTRUCT の場合は PMYSTRUCT を返します。
- GetTypedefFinalBaseType メソッドは、両方の型の MYSTRUCT * を返します
IsTypedef の
IsTypedef メソッドは、型が typedef であるかどうかを確認できる唯一のメソッドです。 GetTypeKind メソッドは、基になる型で呼び出されたかのように動作します。
GetTypedefBaseType を
GetTypedefBaseType メソッドは、typedef の即時定義を返します。 ドキュメントで説明されている例では、次の手順を実行します。
typedef MYSTRUCT *PMYSTRUCT;
typedef PMYSTRUCT PTRMYSTRUCT;
このメソッドは、PMYSTRUCT の場合は MYSTRUCT * を、PTRMYSTRUCT の場合は PMYSTRUCT を返します。
GetTypedefFinalBaseType メソッドは、typedef が定義されている最終的な型を返します。 typedef が別の typedef の定義である場合、typedef ではない型に到達し、その型が返されるまで、これは定義チェーンに従い続けます。 ドキュメントで説明されている例では、次の手順を実行します。
typedef MYSTRUCT *PMYSTRUCT;
typedef PMYSTRUCT PTRMYSTRUCT;
このメソッドは、PMYSTRUCT または PTRMYSTRUCT で呼び出されると MYSTRUCT * を返します。
IDebugHostType2/IDebugHostType 型の作成方法
STDMETHOD(CreatePointerTo)(_In_ PointerKind kind, _COM_Outptr_ IDebugHostType** newType) PURE;
STDMETHOD(CreateArrayOf)(_In_ ULONG64 dimensions, _In_reads_(dimensions) ArrayDimension *pDimensions, _COM_Outptr_ IDebugHostType** newType) PURE;
定数シンボル値: IDebugHostConstant
シンボリック情報に定数値が存在する場所 (特定の値が定数値の場合とそうでないシンボル) の場合、IDebugHostConstant インターフェイスは、このような定数の概念を表します。 これは通常、特定の引数が通常は型であるが、代わりに型以外のテンプレート引数 (定数など) であるテンプレート引数のような場所で使用されます。
IDebugHostConstant インターフェイスは次のように定義されます (IDebugHostSymbol によって実装されるジェネリック メソッドは無視されます)。
DECLARE_INTERFACE_(IDebugHostConstant, IDebugHostSymbol)
{
STDMETHOD(GetValue)(_Out_ VARIANT* value) PURE;
}
GetValue を
GetValue メソッドは、VARIANT にパックされた定数の値を返します。 IDebugHostSymbol の GetType メソッドは、定数の特定の型シンボルを返す可能性があることに注意してください。 このような場合、型シンボルで定義されている定数値のパッキングが、ここで GetValue メソッドによって返されるパッキングと同じであるという保証はありません。
データ メンバー アクセス: IDebugHostField
IDebugHostField クラスは、クラス、構造体、共用体、またはその他の型コンストラクトのデータ メンバーであるシンボルを表します。 空きデータ (グローバル データなど) を表すものではありません。 インターフェイスは次のように定義されます (IDebugHostSymbol にジェネリックメソッドを無視します)。
DECLARE_INTERFACE_(IDebugHostField, IDebugHostSymbol)
{
STDMETHOD(GetLocationKind)(_Out_ LocationKind *locationKind) PURE;
STDMETHOD(GetOffset)(_Out_ ULONG64* offset) PURE;
STDMETHOD(GetLocation)(_Out_ Location* location) PURE;
STDMETHOD(GetValue)(_Out_ VARIANT* value) PURE;
}
GetLocationKind の
GetLocationKind メソッドは、LocationKind 列挙に従ってシンボルが配置されている場所の種類を返します。 このような列挙には、次のいずれかの値を指定できます。
| Enumerant | 意味 |
|---|---|
| LocationMember | フィールドは、クラス、構造体、共用体、またはその他の型コンストラクトの通常のデータ メンバーです。 これには、包含型コンストラクトのベース アドレスに対する相対オフセットがあります。 このようなベース アドレスは、通常、このポインターによって表されます。 フィールドのオフセットは、GetOffset メソッドを使用して取得できます。 LocationMember フィールドの GetLocation メソッドと GetValue メソッドは失敗します。 |
| LocationStatic | フィールドは静的であり、独自のアドレスを持っています。 GetLocation メソッドは、静的フィールドの抽象位置 (アドレスなど) を返します。 LocationStatic フィールドの GetOffset メソッドと GetValue メソッドは失敗します。 |
| LocationConstant | フィールドは定数であり、値を持っています。 GetValue メソッドは定数の値を返します。 LocationConstant フィールドの GetOffset メソッドと GetLocation メソッドは失敗します。 |
| LocationNone | フィールドに場所がありません。 コンパイラによって最適化されているか、宣言されているが定義されていない静的フィールドである可能性があります。 このようなフィールドがどのようになってきたかに関係なく、物理的な存在や価値はありません。 これはシンボル内にあります。 LocationNone フィールドのすべての取得メソッド (GetOffset、GetLocation、および GetValue) は失敗します。 |
GetOffset の
オフセットを持つフィールド (場所の種類が LocationMember を示すフィールドなど) の場合、GetOffset メソッドは、格納型 (このポインター) のベース アドレスからフィールド自体のデータへのオフセットを返します。 このようなオフセットは、常に符号なし 64 ビット値として表されます。 指定されたフィールドに、格納型のベース アドレスからのオフセットである場所がない場合、GetOffset メソッドは失敗します。
GetLocation の
特定の型インスタンスに関係なくアドレスを持つフィールド (たとえば、場所の種類が LocationStatic を示すフィールド) の場合、GetLocation メソッドはフィールドの抽象位置 (アドレス) を返します。 指定されたフィールドに静的な場所がない場合、GetLocation メソッドは失敗します。
GetValue を
シンボリック情報内で定数値が定義されているフィールド (場所の種類が LocationConstant を示すフィールドなど) の場合、GetValue メソッドはフィールドの定数値を返します。 指定されたフィールドに定数値がない場合、GetValue メソッドは失敗します。
無料データ アクセス: IDebugHostData
別の型のメンバーではないモジュール内のデータは、IDebugHostData インターフェイスによって表されます。 そのインターフェイスは次のように定義されます (IDebugHostSymbol にジェネリックメソッドを無視します)。
DECLARE_INTERFACE_(IDebugHostData, IDebugHostSymbol)
{
STDMETHOD(GetLocationKind)(_Out_ LocationKind *locationKind) PURE;
STDMETHOD(GetLocation)(_Out_ Location* location) PURE;
STDMETHOD(GetValue)(_Out_ VARIANT* value) PURE;
}
これらのメソッドはすべて、IDebugHostField の対応するメソッドと意味的に同等です。 唯一の違いは、GetLocationKind メソッドが無料データの LocationMember を返さないということです。
GetLocationKind の
GetLocationKind メソッドは、LocationKind 列挙に従ってシンボルが配置されている場所の種類を返します。 この列挙体の説明については、IDebugHostField のドキュメントを参照してください。
GetLocation の
アドレスを持つデータの場合、GetLocation メソッドはフィールドの抽象位置 (アドレス) を返します。 指定されたデータに静的な場所がない場合、GetLocation メソッドは失敗します。
GetValue を
datawhich の場合、シンボリック情報内で定数値が定義されています (例: location の種類が LocationConstant を示すデータ)、GetValue メソッドはフィールドの定数値を返します。 指定されたデータに定数値がない場合、GetValue メソッドは失敗します。
基本クラス: IDebugHostBaseClass
特定の型の継承階層は、型シンボルの子によって表されます。 特定の型が 1 つ以上の型から派生する (継承が賢明な) 場合、その型のシンボルの SymbolBaseClass 子が 1 つ以上存在します。 これらの SymbolBaseClass シンボルはそれぞれ、特定の型からの即時継承を表します。 基底クラスの名前は、SymbolBaseClass シンボルの名前と、基底クラスの型シンボルの名前の両方です。 SymbolBaseClass シンボルの GetType メソッドを使用して、基底クラス自体の型シンボルを取得できます。 完全な継承階層は、SymbolBaseClass 子シンボルを再帰的に探索することによって走査できます。 これらの基底クラスの各シンボルは、次のように定義されている IDebugHostBaseClass インターフェイスによって表されます (IDebugHostSymbol にジェネリックメソッドを無視します)。
DECLARE_INTERFACE_(IDebugHostBaseClass, IDebugHostSymbol)
{
STDMETHOD(GetOffset)(_Out_ ULONG64* offset) PURE;
}
GetOffset の
GetOffset メソッドは、派生クラスの基底アドレスから基底クラスのオフセットを返します。 このようなオフセットは、ゼロでも、正の符号なし 64 ビット値でもかまいません。
パブリック シンボル: IDebugHostPublic
パブリック シンボルは、シンボル ファイル内のパブリック テーブル内のものを表します。 実際には、アドレスがエクスポートされます。 パブリック シンボルに関連付けられている型情報はありません。アドレスのみ。 呼び出し元がパブリック シンボルを明示的に要求しない限り、デバッグ ホストは、すべての問い合わせに対してプライベート シンボルを返します。 パブリック シンボルは、次のように定義されている IDebugHostPublic インターフェイスによって表されます (IDebugHostSymbol にジェネリックなメソッドは無視されます)。
DECLARE_INTERFACE_(IDebugHostPublic, IDebugHostSymbol)
{
STDMETHOD(GetLocationKind)(_Out_ LocationKind *locationKind) PURE;
STDMETHOD(GetLocation)(_Out_ Location* location) PURE;
}
これらのメソッドはすべて、IDebugHostField の対応するメソッドと意味的に同等です。 唯一の違いは、GetLocationKind メソッドがそのようなシンボルの LocationMember または LocationConstant を返さないということです。
GetLocationKind の
GetLocationKind メソッドは、LocationKind 列挙に従ってシンボルが配置されている場所の種類を返します。 この列挙体の説明については、IDebugHostField のドキュメントを参照してください。
GetLocation の
アドレスを持つデータの場合、GetLocation メソッドはフィールドの抽象位置 (アドレス) を返します。 指定されたパブリックに静的な場所がない場合、GetLocation メソッドは失敗します。
モジュールシグネチャとバージョンマッチング: IDebugHostModuleSignature
モジュール署名は、特定のモジュールが名前付けとバージョン管理に関する一連の条件を満たしているかどうかを確認する手段を表します。 モジュールシグネチャは、IDebugHostSymbols の CreateModuleSignature メソッドを使用して作成されます。 モジュール名と、モジュールのバージョン番号のオプションの範囲を一致させることができます。 このような署名が作成されると、クライアントは次のように定義された IDebugHostModuleSignature インターフェイスを受け取ります。
DECLARE_INTERFACE_(IDebugHostModuleSignature, IUnknown)
{
STDMETHOD(IsMatch)(_In_ IDebugHostModule* pModule, _Out_ bool* isMatch) PURE;
}
IsMatch を
IsMatch メソッドは、特定のモジュール (IDebugHostModule シンボルによって指定された) をシグネチャと比較し、モジュール名とバージョンを署名で示された名前とバージョン範囲と比較します。 指定されたモジュールシンボルがシグネチャと一致するかどうかを示す値が返されます。
型シグネチャと型の一致: IDebugHostTypeSignature
型シグネチャは、特定の型インスタンスが型の名前、型のジェネリック引数、および型が配置されているモジュールに関する一連の条件を満たしているかどうかを確認する手段を表します。 型シグネチャは、IDebugHostSymbols の CreateTypeSignature メソッドを使用して作成されます。 このような署名が作成されると、クライアントは次のように定義された IDebugHostTypeSignature インターフェイスを受け取ります。
DECLARE_INTERFACE_(IDebugHostTypeSignature, IUnknown)
{
STDMETHOD(GetHashCode)(_Out_ ULONG* hashCode) PURE;
STDMETHOD(IsMatch)(_In_ IDebugHostType* type, _Out_ bool* isMatch, _COM_Outptr_opt_ IDebugHostSymbolEnumerator** wildcardMatches) PURE;
STDMETHOD(CompareAgainst)(_In_ IDebugHostTypeSignature* typeSignature, _Out_ SignatureComparison* result) PURE;
}
GetHashCode を する
GetHashCode メソッドは、型シグネチャの 32 ビット ハッシュ コードを返します。 デバッグ ホストは、型インスタンスに対して返されるハッシュ コードと、型シグネチャに対して返されるハッシュ コードの間に、実装内に同期があることを保証します。 グローバル一致を除き、型インスタンスが型シグネチャと一致できる場合、両方とも同じ 32 ビット ハッシュ コードを持ちます。 これにより、データ モデル マネージャーに登録されている型インスタンスと多数の型シグネチャの間で、初期の迅速な比較と照合が可能になります。
IsMatch を
IsMatch メソッドは、特定の型インスタンスが型シグネチャで指定された条件と一致するかどうかを示す値を返します。 その場合は、型シグネチャのワイルドカードと一致した型インスタンスの特定の部分 (シンボルとして) をすべて示す列挙子と同様に、これが返されます。
CompareAgainst メソッドは、型シグネチャを別の型シグネチャと比較し、2 つのシグネチャの比較方法を返します。 返される比較結果は、次のように定義されている SignatureComparison 列挙体のメンバーです。
| Enumerant | 意味 |
|---|---|
| 無関係 | 比較される 2 つのシグネチャまたは型の間にリレーションシップはありません。 |
| 紛らわしい | 一方のシグネチャまたは型は、他方とあいまいに比較されます。 2 つの型シグネチャの場合、どちらのシグネチャとも同じように一致する可能性のある型インスタンスがあることを意味します。 例として、次に示す 2 つの型シグネチャはあいまいです。 シグネチャ 1: std::pair<*, int> シグネチャ 2: std::pair<int,*>、型インスタンス std::pair<int, int> がいずれか 1 つの等しく一致するためです (どちらも具象とワイルドカードが一致します)。 |
| LessSpecific | 一方の署名または型は、他のシグネチャよりも具体的ではありません。 多くの場合、これは、より具体的な署名が具象型を持つワイルドカードを持っていることを意味します。 例として、以下の最初の署名は 2 番目の署名よりも具体的ではありません。 署名 1: std::pair<*, int> 署名 2: std::pair<int, int> はワイルドカード (*) を持ち、2 つ目には具象型 (int) があるためです。 |
| MoreSpecific | 一方のシグネチャまたは型は、他のシグネチャよりも具体的です。 多くの場合、これは、より具体的なシグネチャが具体的な型を持ち、具体的でない署名にワイルドカードがあることを意味します。 たとえば、次の最初の署名は、2 番目の署名よりも具体的です。 署名 1: std::pair<int, int> 署名 2: std::pair<*, int>、2 番目の型にはワイルドカード (*) を持つ具象型 (int) があるためです。 |
| 同じ | 2 つのシグネチャまたは型は同じです。 |
関連項目
このトピックは、C++ からアクセスできるインターフェイス、C++ ベースのデバッガー拡張機能の構築に使用する方法、および C++ データ モデル拡張機能から他のデータ モデルコンストラクト (JavaScript や NatVis など) を使用する方法について説明するシリーズの一部です。