Debugger Data Model C++ のスクリプト
このトピックでは、Debugger Data Model C++ スクリプトを使用して、スクリプトを使用したデバッガー エンジンでの自動化をサポートする方法について説明します。
Debugger Data Model でのスクリプト管理
オブジェクトの作成と拡張性に関する中心的な権限としてのデータ モデル マネージャーの役割に加えて、スクリプトの抽象的な概念の管理も担当します。 データ モデル マネージャーのスクリプト マネージャー部分の観点から見ると、スクリプトとは、新しい機能を拡張したりデータ モデルに提供したりするために、プロバイダーによって動的に読み込み、アンロード、デバッグできるものを指します。
スクリプト プロバイダーは、言語 (NatVis、JavaScript など) をデータ モデルにブリッジするコンポーネントです。 プロバイダーが扱う 1 つ以上のファイル拡張子 (".NatVis"、".js" など) がスクリプト プロバイダーによって登録されると、デバッガー クライアントまたはユーザー インターフェイスは、特定の拡張子を持つスクリプト ファイルのロードをプロバイダーに委任できるようになります。
コア スクリプト マネージャー: IDataModelScriptManager
コア スクリプト マネージャー インターフェイスは次のように定義されます。
DECLARE_INTERFACE_(IDataModelScriptManager, IUnknown)
{
STDMETHOD(GetDefaultNameBinder)(_COM_Outptr_ IDataModelNameBinder **ppNameBinder) PURE;
STDMETHOD(RegisterScriptProvider)(_In_ IDataModelScriptProvider *provider) PURE;
STDMETHOD(UnregisterScriptProvider)(_In_ IDataModelScriptProvider *provider) PURE;
STDMETHOD(FindProviderForScriptType)(_In_ PCWSTR scriptType, _COM_Outptr_ IDataModelScriptProvider **provider) PURE;
STDMETHOD(FindProviderForScriptExtension)(_In_ PCWSTR scriptExtension, _COM_Outptr_ IDataModelScriptProvider **provider) PURE;
STDMETHOD(EnumerateScriptProviders)(_COM_Outptr_ IDataModelScriptProviderEnumerator **enumerator) PURE;
}
GetDefaultNameBinder メソッドは、データ モデルの既定のスクリプト名バインダーを返します。 名前バインダーは、オブジェクトのコンテキスト内で名前を解決するコンポーネントです。 たとえば、式 "foo.bar" を指定すると、オブジェクト foo のコンテキストで名前バーを解決するために名前バインダーが呼び出されます。 ここで返されるバインダーは、データ モデルの既定の規則のセットに従います。 スクリプト プロバイダーは、このバインダーを使用して、プロバイダー間の名前解決の一貫性を提供できます。
RegisterScriptProvider メソッドは、新しい言語をデータ モデルにブリッジできる新しいスクリプト プロバイダーが存在することをデータ モデルに通知します。 このメソッドが呼び出されると、スクリプト マネージャーは、指定されたスクリプト プロバイダーを直ちにコールバックし、管理するスクリプトのプロパティを確認します。 指定されたスクリプト プロバイダが示す名前またはファイル拡張子で既にプロバイダーが登録されている場合、このメソッドは失敗します。 特定の名前またはファイル拡張子のハンドラーとして登録できるのは、1 つのスクリプト プロバイダーのみです。
UnregisterScriptProvider メソッドは、RegisterScriptProvider メソッドの呼び出しを元に戻します。 渡されたスクリプト プロバイダーによって指定された名前とファイル拡張子は、そのスクリプトに関連付けられなくなります。 登録解除後も、スクリプト プロバイダーへの未処理の COM 参照が多数存在する可能性があることに注意してください。 このメソッドは、特定のスクリプト プロバイダーが管理する型のスクリプトの読み込み/作成のみを防止します。 そのプロバイダーによって読み込まれたスクリプトがまだ読み込まれている場合、またはデバッガー (またはデータ モデル) のオブジェクト モデルを操作している場合、それらの操作にはスクリプトへの参照が残っている可能性があります。 スクリプト内のコンストラクトを直接参照するデータ モデル、メソッド、またはオブジェクトが存在することも考えられます。 スクリプト プロバイダーは、そのような事態に対処できるように準備する必要があります。
FindProviderForScriptType メソッドは、このメソッドで示されているスクリプト型の文字列を持つプロバイダーをスクリプト マネージャーで検索します。 見つからない場合、このメソッドは失敗します。それ以外の場合は、検索されたスクリプト プロバイダーが呼び出し元に返されます。
EnumerateScriptProviders メソッドは、RegisterScriptProvider メソッドの事前呼び出しによってスクリプト マネージャーに登録されたすべてのスクリプト プロバイダーを列挙する列挙子を返します。
スクリプト プロバイダー列挙: IDataModelScriptProviderEnumerator
EnumerateScriptProviders メソッドは、次の形式の列挙子を返します。
DECLARE_INTERFACE_(IDataModelScriptProviderEnumerator, IUnknown)
{
STDMETHOD(Reset)() PURE;
STDMETHOD(GetNext)(_COM_Outptr_ IDataModelScriptProvider **provider) PURE;
}
Reset メソッドは、最初の要素を返す前の位置に列挙子を移動します。
GetNext メソッドは、列挙子を 1 つの要素の前に移動し、その要素にあるスクリプト プロバイダーを返します。 列挙子が列挙の末尾に達すると、E_BOUNDS が返されます。 このエラーを受け取った後に GetNext メソッドを呼び出すと、E_BOUNDS が無期限に返されます。
Debugger Data Model C++ スクリプト用ホスト インターフェイス
スクリプトでのホストの役割
デバッグ ホストは、デバッグ ターゲットの型システムの性質を理解し、デバッグ ターゲットの言語で式を評価するために、非常に低いレベルのインターフェイスのシリーズを公開します。通常、スクリプトのようなより高いレベルのコンストラクトを使用する必要はありません。 このような機能は、デバッガー アプリケーション全体、またはこれらの機能を提供する拡張機能に任されています。 ただし、この動作には例外があります。 データ モデルが提供する全体的なスクリプト エクスペリエンスに参加するデバッグ ホストは、スクリプトにコンテキストを提供するために、いくつかの単純なインターフェイスを実装する必要があります。 実際、デバッグ ホストは、スクリプト環境のデータ モデルの名前空間内において、関数やその他のスクリプトによって提供される機能を配置する場所を制御します。 このプロセスに関与することで、ホストは、たとえば、式エバリュエーターなどでそのような関数の使用を許可する (または許可しない) ことができます。 ここでホストから見て関係するインターフェイスは次のとおりです。
Interface | 説明 |
---|---|
IDebugHostScriptHost | スクリプト環境の一部としてデバッグ ホストの機能を示すインターフェイス。 このインターフェイスでは、オブジェクトを配置する場所をスクリプト エンジンに通知するコンテキストを作成できます。 |
IDataModelScriptHostContext | スクリプト プロバイダーが、スクリプトの内容のコンテナーとして使用するホスト インターフェイスです。 スクリプトの内容が、デバッガー アプリケーションのオブジェクト モデルに対して実行する操作以外にどのように表示されるかは、具体的なデバッグ ホストにゆだねられています。 このインターフェイスによって、スクリプト プロバイダーは、コンテンツを配置する場所に関する情報を取得できます。 詳細については、このトピックで後述する「Data Model C++ スクリプト インターフェイス」を参照してください。 |
デバッグ ホストのスクリプト ホスト: IDebugHostScriptHost
IDebugHostScriptHost インターフェイスは、スクリプトプロバイダが、新しく作成されたスクリプトのデバッグホストからコンテキストを取得するために使用するインターフェイスです。 このコンテキストには、スクリプト プロバイダーがデータ モデルとスクリプト環境の間に任意のブリッジを配置できるオブジェクト (デバッグ ホストが提供) が含まれます。 このようなブリッジは、たとえば、スクリプト関数を呼び出すデータ モデル メソッドなどです。 これにより、データ モデル側の呼び出し元は、IModelMethod インターフェイスの Call メソッドを使用してスクリプト メソッドを呼び出すことができます。
IDebugHostScriptHost インターフェイスは次のように定義されています。
DECLARE_INTERFACE_(IDebugHostScriptHost, IUnknown)
{
STDMETHOD(CreateContext)(_In_ IDataModelScript* script, _COM_Outptr_ IDataModelScriptHostContext** scriptContext) PURE;
}
CreateContext メソッドは、スクリプト プロバイダーによって呼び出され、スクリプトの内容を配置する新しいコンテキストを作成します。 このようなコンテキストは、IDataModelScriptHostContext インターフェイスによって表されます。このインターフェイスの詳細については、「Data Model C++ スクリプト インターフェイス」のページを参照してください。
Debugger Data Model C++ のスクリプト インターフェイス
スクリプトおよびスクリプト インターフェイス
データ モデルの全体的なアーキテクチャは、サード パーティが、一部の言語とデータ モデルのオブジェクト モデルの間のブリッジを定義できるように設計されています。 通常、ブリッジされる言語はスクリプト言語です。データ モデルの環境は非常に動的であるためです。 データ モデルの言語とオブジェクト モデルの間のこのブリッジを定義して実装するコンポーネントは、スクリプト プロバイダーと呼ばれます。 スクリプト プロバイダーは、初期化されると自身をデータ モデル マネージャのスクリプト マネージャー部分に登録します。これにより、拡張性を管理する任意のインタフェースが、スクリプト プロバイダの管理する言語に書かれたスクリプトを編集、読み込み、アンロード、および場合によってはデバッグできるようになります。
Windows 用のデバッグ ツールでは現在、次の 2 つのスクリプト プロバイダーが定義されています。
- NatVis プロバイダー。 このプロバイダーは、DbgEng.dll 内に埋め込まれており、NatVis XML とデータ モデルの間のブリッジにより、ネイティブ/言語のデータ型を視覚化できます。
- JavaScript プロバイダー。 このプロバイダーは、レガシ デバッガー拡張機能 (JsProvider.dll) 内に含まれています。 JavaScript 言語で記述されたスクリプトとデータ モデルの間でブリッジされるため、任意の形式のデバッガー制御と拡張性が可能になります。
他の言語 (Python など) をデータ モデルにブリッジする新しいプロバイダーを記述できます。 現在、このような機能は、読み込み目的で従来のデバッガー拡張機能にカプセル化されています。 スクリプト プロバイダー自体は、レガシ エンジン インターフェイスとの依存関係を最小限に抑え、可能な場合にのみデータ モデル API を利用する必要があります。 これにより、プロバイダーが他の環境に移植しやすくなります。
スクリプト プロバイダーに関連するインターフェイスには、2 つのクラスがあります。 インターフェイスの 1 つ目のクラスは、スクリプト プロバイダーとそれらが管理するスクリプトの一般的な管理を目的としています。 インターフェイスの 2 番目のクラスは、スクリプト のデバッグをサポートします。 最初のセットのサポートは必須ですが、2 つ目のセットのサポートは省略可能であり、プロバイダーによっては意味がない場合があります。
一般的な管理インターフェイスは次のとおりです。
Interface | 説明 |
---|---|
IDataModelScriptProvider | スクリプト プロバイダーが実装すべき必須のコア インターフェイス。 データ モデル マネージャーのスクリプト マネージャー部分に登録されることで、特定の種類のスクリプトのプロバイダーのサポートをアドバタイズし、特定のファイル拡張子に対して登録するインターフェイスです |
IDataModelScript | プロバイダーによって管理されている特定のスクリプトの抽象化。 読み込みや編集対象の各スクリプトには、個別の IDataModelScript インスタンスがあります |
IDataModelScriptClient | スクリプト プロバイダーが、ユーザー インターフェイスに情報を通信するために使用するクライアント インターフェイス。 スクリプト プロバイダーでは、このインターフェイスは実装されません。 スクリプト プロバイダーを使用するデータ モデルをホストするアプリケーションでは実装されます。 スクリプト プロバイダーは、スクリプト クライアントのメソッドを呼び出して、状態やエラーなどを報告します。 |
IDataModelScriptHostContext | スクリプト プロバイダーが、スクリプトの内容のコンテナーとして使用するホスト インターフェイスです。 スクリプトの内容が、デバッガー アプリケーションのオブジェクト モデルに対して実行する操作以外にどのように表示されるかは、具体的なデバッグ ホストにゆだねられています。 このインターフェイスによって、スクリプト プロバイダーは、コンテンツを配置する場所に関する情報を取得できます。 |
IDataModelScriptTemplate | スクリプト プロバイダーは、ユーザーがスクリプトを作成するための開始点として機能する 1 つ以上のテンプレートを提供できます。 組み込みのエディターを提供するデバッガー アプリケーションは、このインターフェイスを使用することで、プロバイダーによってアドバタイズされたテンプレート コンテンツで新しいスクリプトを事前に入力できます。 |
IDataModelScriptTemplateEnumerator | スクリプト プロバイダーが、自身のサポートするすべてのテンプレートをアドバタイズするために使用する列挙子インターフェイス。 |
IDataModelNameBinder | 名前バインダー - コンテキスト内の名前を値に関連付けることができるオブジェクト。 名前バインダーは、たとえば "foo.bar" という式がある場合に、オブジェクト "foo" のコンテキストで名前 "bar" をバインドして、それに対する値や参照を生成できます。 通常、名前バインダーはスクリプト プロバイダーによって実装されるのではなく、既定のバインダーがデータ モデルから取得されて、スクリプト プロバイダーによって使用されます |
デバッグ インターフェイスは次のとおりです。
Interface | 説明 |
---|---|
IDataModelScriptDebug | スクリプトをデバッグ可能にするためにスクリプト プロバイダーが提供する必要があるコア インターフェイス。 スクリプトがデバッグ可能な場合、IDataModelScript インターフェイスの実装クラスでは、IDataModelScriptDebug の QueryInterface が必要です。 |
IDataModelScriptDebugClient | スクリプト デバッグの機能を提供するユーザー インターフェイスは、IDataModelScriptDebugClient インターフェイスを実装します。 スクリプト プロバイダーは、このインターフェイスを使用してデバッグ情報 (発生したイベント、ブレークポイントなど) を前後に渡します。 |
IDataModelScriptDebugStack | スクリプト プロバイダーは、このインターフェイスを実装して、呼び出し履歴の概念をスクリプト デバッガーに公開します。 |
IDataModelScriptDebugStackFrame | スクリプト プロバイダーは、このインターフェイスを実装して、呼び出し履歴内の特定のスタック フレームの概念を公開します。 |
IDataModelScriptDebugVariableSetEnumerator | スクリプト プロバイダーは、このインターフェイスを実装して、一連の変数を公開します。 このセットは、関数へのパラメーターのセット、ローカル変数のセット、または特定のスコープ内の変数のセットを表します。 正確な意味は、インターフェイスの取得方法によって異なります。 |
IDataModelScriptDebugBreakpoint | スクリプト プロバイダーは、このインターフェイスを実装して、スクリプト内の特定のブレークポイントの概念と制御を公開します。 |
IDataModelScriptDebugBreakpointEnumerator | スクリプト プロバイダーはこれを実装して、スクリプト内に現在存在するすべてのブレークポイントを列挙します (有効かどうかに関係なく)。 |
コア スクリプト プロバイダー: IDataModelScriptProvider
スクリプト プロバイダーにする拡張機能は、IDataModelScriptProvider インターフェイスの実装を提供し、RegisterScriptProvider メソッドを使用してデータ モデル マネージャーのスクリプト マネージャー部分に登録する必要があります。 実装が必要なこのコア インターフェイスは、次のように定義されています。
DECLARE_INTERFACE_(IDataModelScriptProvider, IUnknown)
{
STDMETHOD(GetName)(_Out_ BSTR *name) PURE;
STDMETHOD(GetExtension)(_Out_ BSTR *extension) PURE;
STDMETHOD(CreateScript)(_COM_Outptr_ IDataModelScript **script) PURE;
STDMETHOD(GetDefaultTemplateContent)(_COM_Outptr_ IDataModelScriptTemplate **templateContent) PURE;
STDMETHOD(EnumerateTemplates)(_COM_Outptr_ IDataModelScriptTemplateEnumerator **enumerator) PURE;
}
GetName メソッドは、プロバイダーが SysAllocString メソッドを介して割り当てられた文字列として管理するスクリプトの型 (または言語) の名前を返します。 呼び出し元は、SysFreeString を使用して返された文字列を解放する役割を担います。 このメソッドから返される文字列としては、たとえば "JavaScript" や "NatVis" が考えられます。 返される文字列は、データ モデルをホストしているデバッガー アプリケーションのユーザー インターフェイスに表示される可能性があります。 2 つのスクリプト プロバイダーが同じ名前を返す可能性はありません (大文字と小文字は区別されません)。
GetExtension メソッドは、このプロバイダーによって管理されるスクリプトのファイル拡張子 (ドットなし) を、SysAllocString メソッドを使用して割り当てられた文字列として返します。 データ モデルをホストするデバッガー アプリケーション (スクリプトのサポートあり) は、この拡張子を持つスクリプト ファイルの開きをスクリプト プロバイダーに委任します。 呼び出し元は、SysFreeString を使用して返された文字列を解放する役割を担います。 このメソッドから返される文字列としては、たとえば "js" や "NatVis" が考えられます。
CreateScript メソッドは、新しいスクリプトを作成するために呼び出されます。 スクリプト プロバイダーは、このメソッドが呼び出されるたびに、返された IDataModelScript インターフェイスが表す新しい空のスクリプトを返す必要があります。 このメソッドは、ユーザー インターフェイスがユーザーによる編集用の新しい空のスクリプトを作成しているかどうか、またデバッガー アプリケーションがディスクからスクリプトを読み込むかどうかに関係なく呼び出されることに注意してください。 プロバイダーはファイル I/O に関与しません。 IDataModelScript のメソッドに渡されるストリームを介して、ホスティング アプリケーションからの要求のみを処理します。
GetDefaultTemplateContent メソッドは、プロバイダーの既定のテンプレート コンテンツのインターフェイスを返します。 これは、スクリプト プロバイダーがスクリプトの編集ウィンドウを新しく作成したときに、そのウィンドウに事前入力される内容です。 スクリプト プロバイダーにテンプレートが存在しない (またはテンプレート コンテンツが既定のコンテンツとして指定されていない) 場合、スクリプト プロバイダーはこのメソッドから E_NOTIMPL を返す可能性があります。
EnumerateTemplates メソッドは、スクリプト プロバイダーによって提供されるさまざまなテンプレートを列挙できる列挙子を返します。 テンプレート コンテンツは、スクリプト プロバイダーが新しいスクリプトを作成したときに、編集ウィンドウに "事前入力" される内容です。 複数の異なるテンプレートがサポートされている場合、それらのテンプレートに名前を付けることができます ("命令型スクリプト"、"拡張スクリプト" など)。データ モデルをホストするデバッガー アプリケーションは、ユーザーに "テンプレート" を表示する方法を選択できます。
コア スクリプト インターフェイス: IDataModelScript
IDataModelScript インターフェイスは、プロバイダーによって実装される個々のスクリプトを管理するメインのインターフェイスです。 このインターフェイスを実装するコンポーネントは、クライアントが新しい空のスクリプトを作成し、IDataModelScriptProvider で CreateScript メソッドを呼び出すときに返されます。
プロバイダーによって作成される各スクリプトは、独立したサイロ内にある必要があります。 データ モデルを介して外部オブジェクトと明示的にやり取りする場合を除き、1 つのスクリプトが別のスクリプトに影響を与えてはなりません。 たとえば、2 つのスクリプトは、何らかの型または概念を拡張できます (デバッガーのプロセスの概念など)。 どちらのスクリプトも、外部プロセス オブジェクトを介して互いのフィールドにアクセスできます。
このインターフェイスは次のように定義されます。
DECLARE_INTERFACE_(IDataModelScript, IUnknown)
{
STDMETHOD(GetName)(_Out_ BSTR *scriptName) PURE;
STDMETHOD(Rename)(_In_ PCWSTR scriptName) PURE;
STDMETHOD(Populate)(_In_ IStream *contentStream) PURE;
STDMETHOD(Execute)(_In_ IDataModelScriptClient *client) PURE;
STDMETHOD(Unlink)() PURE;
STDMETHOD(IsInvocable)(_Out_ bool *isInvocable) PURE;
STDMETHOD(InvokeMain)(_In_ IDataModelScriptClient *client) PURE;
}
GetName メソッドは、SysAllocString 関数を使用して、割り当てられた文字列としてスクリプトの名前を返します。 スクリプトにまだ名前がない場合、メソッドは null BSTR を返す必要があります。 この場合も失敗しません。 Rename メソッドの呼び出しによってスクリプトの名前が明示的に変更された場合、GetName メソッドは新しく割り当てられた名前を返す必要があります。
Rename メソッドは、スクリプトに新しい名前を割り当てます。 この名前を保存し、GetName メソッドの呼び出し時にそれを返すのは、スクリプト実装の役割です。 これは、多くの場合、ユーザー インターフェイスがスクリプトとして新しい名前に保存することを選択したときに呼び出されます。 スクリプトの名前を変更すると、ホスト アプリケーションがスクリプトの内容を投影する場所に影響する可能性があることに注意してください。
Populate メソッドは、クライアントによって呼び出されて、スクリプトの "コンテンツ" を変更または同期します。 これにより、スクリプトのコードが変更されたことがスクリプト プロバイダに通知されます。 このメソッドでは、スクリプトが実行されたり、スクリプトが操作するオブジェクトが変更されたりするわけではないことに注意してください。 このメソッドは、スクリプト プロバイダーが独自の内部状態を同期できるようにスクリプトの内容が変更されたことを示す通知にすぎません。
Execute メソッドは、最後に成功した Populate 呼び出しによって指示されたスクリプトの内容を実行し、その内容に従ってデバッガーのオブジェクト モデルを変更します。 言語 (またはスクリプト プロバイダー) で "メイン関数" (ユーザー インターフェイスでたとえば [Execute スクリプト] などの名前のボタンをクリックしたときに呼びされる関数) が定義されている場合、そのような "メイン関数" は Execute 操作中には呼び出されません。 Execute 操作は、初期化操作とオブジェクト モデル操作のみ (ルート コードの実行や拡張ポイントの設定など) を実行するものと考えることができます。
Unlink メソッドは Execute 操作を元に戻します。 スクリプトの実行中に確立されたオブジェクト モデル操作または拡張ポイントは元に戻されます。 リンク解除操作の後、スクリプトは Execute の呼び出しを介して再実行されるか、または解放される可能性があります。
IsInvocable メソッドは、スクリプトが呼び出し可能かどうかを返します。つまり、言語またはプロバイダーによって定義された "メイン関数" が存在するかどうかが返されます。 このような "メイン関数 "は、コンセプト的には、ユーザー インターフェイスで想像上の "スクリプト実行" ボタンが押された場合に、スクリプト作者が呼び出すことができます。
スクリプト内に UI 呼び出しからの実行を意図した "メイン関数" が存在する場合は、IsInvocable メソッドからの真の戻り値を使用してその旨が示されます。 その後、ユーザー インターフェイスは InvokeMain メソッドを呼び出して、スクリプトを実際に "呼び出す" ことができます。 これは、すべてのルート コードを実行し、スクリプトを基になるホストの名前空間にブリッジする Execute とは異なります。
** スクリプト クライアント: IDataModelScriptClient **
スクリプトを管理し、この概念に関するユーザー インターフェイス (グラフィカルまたはコンソール) を持つデータ モデルをホストするアプリケーションは、IDataModelScriptClient インターフェイスを実装します。 このインターフェイスは、実行中または呼び出し中に任意のスクリプト プロバイダーまたはスクリプトに渡され、それによってエラーとイベントの情報がユーザー インターフェイスに渡されます。
IDataModelScriptClient インターフェイスは次のように定義されています。
DECLARE_INTERFACE_(IDataModelScriptClient, IUnknown)
{
STDMETHOD(ReportError)(_In_ ErrorClass errClass, _In_ HRESULT hrFail, _In_opt_ PCWSTR message, _In_ ULONG line, _In_ ULONG position) PURE;
}
スクリプトの実行中または呼び出し中にエラーが発生した場合、スクリプト プロバイダーは ReportError メソッドを呼び出してエラーをユーザー インターフェイスに通知します。
スクリプトのホスト コンテキスト: IDataModelScriptHostContext
デバッグ ホストは、データ モデルスクリプトコンテンツを投影する方法に影響を及ぼします。 各スクリプトは、スクリプトにブリッジを配置するコンテキスト (たとえば、呼び出すことができる関数オブジェクトなど) をホストに要求する必要があります。このコンテキストは、IDebugHostScriptHost で CreateContext メソッドを呼び出して取得され、IDataModelScriptHostContext を取得します。
IDataModelScriptHostContext インターフェイスは次のように定義されています。
DECLARE_INTERFACE_(IDataModelScriptHostContext, IUnknown)
{
STDMETHOD(NotifyScriptChange)(_In_ IDataModelScript* script, _In_ ScriptChangeKind changeKind) PURE;
STDMETHOD(GetNamespaceObject)(_COM_Outptr_ IModelObject** namespaceObject) PURE;
}
関連付けられたコンテキストで、NotifyScriptChange メソッドのメソッド呼び出しによって特定の操作が発生したときに、スクリプト プロバイダーは、デバッグ ホストに通知する必要があります。 このような操作は、ScriptChangeKind 列挙型のメンバーとして定義されます
GetNamespaceObject メソッドは、スクリプト プロバイダーがデータ モデルとスクリプトの間にブリッジを配置できるオブジェクトを返します。 たとえば、スクリプト プロバイダーがデータ モデル メソッド オブジェクト (IModelObject にボックス化された IModelMethod インターフェイス) を配置し、その実装がスクリプト内の対応する名前付き関数を呼び出します。
新しく作成されたスクリプトのテンプレート: IDataModelScriptTemplate
新しいスクリプトの事前入力されたコンテンツを表示するスクリプト プロバイダー (たとえば、ユーザーがデバッガー のユーザー インターフェイスでスクリプトを記述できるようにする場合) は、1 つ以上のスクリプト テンプレートを提供することでこれを行うことができます。 このようなテンプレートは、IDataModelScriptTemplate インターフェイスを実装するコンポーネントであり、スクリプト プロバイダーの GetDefaultTemplate メソッドまたは EnumerateTemplates メソッドを介して返されます。
IDataModelScriptTemplate インターフェイスは次のように定義されています。
DECLARE_INTERFACE_(IDataModelScriptTemplate, IUnknown)
{
STDMETHOD(GetName)(_Out_ BSTR *templateName) PURE;
STDMETHOD(GetDescription)(_Out_ BSTR *templateDescription) PURE;
STDMETHOD(GetContent)(_COM_Outptr_ IStream **contentStream) PURE;
}
GetName メソッドは、テンプレートの名前を返します。 テンプレートに名前が存在しない場合、このメソッドは、E_NOTIMPL で失敗する可能性があります。 既定のテンプレートが 1 つの場合 (存在する場合) は、名前は必要ありません。 その他のすべてのテンプレートには名前が必要です。 これらの名前は、作成するテンプレートを選択するためのメニューの一部として、ユーザー インターフェイスに表示することができます。
GetDescription メソッドは、テンプレートの説明を返します。 このような説明は、テンプレートがどのような用途で設計されているかをユーザーが理解できるように、よりわかりやすいインターフェイスでユーザーに提示されます。 テンプレートに説明がない場合は、このメソッドから E_NOTIMPL を返すことができます。
GetContent メソッドは、テンプレートのコンテンツ (またはコード) を返します。 これは、ユーザーがこのテンプレートから新しいスクリプトを作成するように選択した場合に、編集ウィンドウに事前入力されます。 テンプレートは、クライアントがプルできるコンテンツに対して標準ストリームを作成 (および返す) 役割を担います。
プロバイダーのテンプレート コンテンツの列挙: IDataModelScriptTemplateEnumerator
スクリプト プロバイダーは、一部のユーザー インターフェイスで新しく作成されたスクリプトにコンテンツを事前入力する 1 つ以上のテンプレートを提供できます。 これらのテンプレートのいずれかが提供されている場合、スクリプト プロバイダーは、EnumerateTemplates メソッドの呼び出し時に返される列挙子を実装する必要があります。
このような列挙子は、IDataModelScriptTemplateEnumerator インターフェイスの実装であり、次のように定義されます。
DECLARE_INTERFACE_(IDataModelScriptTemplateEnumerator, IUnknown)
{
STDMETHOD(Reset)() PURE;
STDMETHOD(GetNext)(_COM_Outptr_ IDataModelScriptTemplate **templateContent) PURE;
}
Reset メソッドは、最初のテンプレートが生成される前に、列挙子を最初に作成されたときの位置にリセットします。
GetNext メソッドは、列挙子を次のテンプレートに移動し、それを返します。 列挙子は、列挙の最後に E_BOUNDS を返します。 E_BOUNDS マーカーにヒットすると、列挙子は Reset 呼び出しが行われるまで E_BOUNDS エラーを無期限に生成し続けます。
名前の意味の解決: IDataModelNameBinder
データ モデルは、スクリプト プロバイダーが、さまざまなスクリプト プロバイダー全体で動作する特定のコンテキスト (たとえば、foo.bar の bar の意味の定義) で、特定の名前の意味を判断するための標準的な方法を提供します。 このメカニズムは名前バインダーと呼ばれ、IDataModelNameBinder インターフェイスによって表されます。 このようなバインダーは、名前が解決される方法と、オブジェクトで名前が複数回定義される競合解決に対処する方法に関する一連の規則をカプセル化します。 これらのルールには、その一部として、投影された名前 (データ モデルによって追加された名前) がネイティブ名 (デバッグ対象の言語の型システムにおける名前) にどのように解決されるかなどが含まれます。
スクリプト プロバイダー間で一貫性を確保するために、データ モデルのスクリプト マネージャーは既定の名前バインダーを提供します。 この既定の名前バインダーは、IDataModelScriptManager インターフェイスの GetDefaultNameBinder メソッドの呼び出しを介して取得できます。 名前バインダーのインターフェイスは次のように定義されます。
DECLARE_INTERFACE_(IDataModelNameBinder, IUnknown)
{
STDMETHOD(BindValue)(_In_ IModelObject* contextObject, _In_ PCWSTR name, _COM_Errorptr_ IModelObject** value, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
STDMETHOD(BindReference)(_In_ IModelObject* contextObject, _In_ PCWSTR name, _COM_Errorptr_ IModelObject** reference, _COM_Outptr_opt_result_maybenull_ IKeyStore** metadata) PURE;
STDMETHOD(EnumerateValues)(_In_ IModelObject* contextObject, _COM_Outptr_ IKeyEnumerator** enumerator) PURE;
STDMETHOD(EnumerateReferences)(_In_ IModelObject* contextObject, _COM_Outptr_ IKeyEnumerator** enumerator) PURE;
}
BindValue メソッドは、バインド規則のセットに従って、指定されたオブジェクトに対して同等の contextObject.name を実行します。 このバインディングの結果は値です。 値として、基になるスクリプト プロバイダーは値を使用して名前への割り当てを実行できません。
BindReference メソッドは、バインド規則のセットに従って、指定されたオブジェクトに対して同等の contextObject.name も実行するという点で BindValue に似ています。 ただし、このメソッドからのバインドの結果は、値ではなく参照です。 参照として、スクリプト プロバイダーは参照を利用して名前への割り当てを実行できます。
EnumerateValues メソッドは、BindValue メソッドの規則に従ってオブジェクトにバインドする名前と値のセットを列挙します。 同じ値を持つ複数の名前 (基本クラス、親モデルなど) を返す可能性がある IModelObject の EnumerateKeys、EnumerateValues、および同様のメソッドとは異なり、この列挙子は BindValue と BindReference でバインドされる特定の名前のセットのみを返します。 名前が重複することはありません。 名前バインダーを使用してオブジェクトを列挙すると、IModelObject メソッドを呼び出すよりもコストが大幅に高くなることに注意してください。
EnumerateReferences メソッドは、BindReference メソッドの規則に従ってオブジェクトにバインドする一連の名前とそれらに対する参照を列挙します。 同じ値を持つ複数の名前 (基本クラス、親モデルなど) を返す可能性がある IModelObject の EnumerateKeys、EnumerateValues、および同様のメソッドとは異なり、この列挙子は BindValue と BindReference でバインドされる特定の名前のセットのみを返します。 名前が重複することはありません。 名前バインダーを使用してオブジェクトを列挙すると、IModelObject メソッドを呼び出すよりもコストが大幅に高くなることに注意してください。
Debugger Data Model C++ スクリプト デバッグ インターフェイス
データ モデルのスクリプト プロバイダーのインフラストラクチャには、スクリプトのデバッグに関するコンセプトも用意されています。 デバッグ機能をデバッグ ホストとデータ モデルをホストするデバッガー アプリケーションに公開するスクリプトは、IDataModelScript インターフェイスに加えて、デバッグ可能なスクリプトで IDataModelScriptDebug インターフェイスを実装することで、これを実現することができます。 スクリプトにこのインターフェイスが存在することは、デバッグ可能であることをインフラストラクチャに示します。
IDataModelScriptDebug インターフェイスは、スクリプト プロバイダーのデバッグ機能にアクセスするための開始点ですが、全体的なデバッグ機能を提供する際に他の一連のインターフェイスによって結合されます。
デバッグ インターフェイスは次のとおりです。
Interface | 説明 |
---|---|
IDataModelScriptDebug | スクリプトをデバッグ可能にするためにスクリプト プロバイダーが提供する必要があるコア インターフェイス。 スクリプトがデバッグ可能な場合、IDataModelScript インターフェイスの実装クラスでは、IDataModelScriptDebug の QueryInterface が必要です。 |
IDataModelScriptDebugClient | スクリプト デバッグの機能を提供するユーザー インターフェイスは、IDataModelScriptDebugClient インターフェイスを実装します。 スクリプト プロバイダーは、このインターフェイスを使用してデバッグ情報 (発生したイベント、ブレークポイントなど) を前後に渡します。 |
IDataModelScriptDebugStack | スクリプト プロバイダーは、このインターフェイスを実装して、呼び出し履歴の概念をスクリプト デバッガーに公開します。 |
IDataModelScriptDebugStackFrame | スクリプト プロバイダーは、このインターフェイスを実装して、呼び出し履歴内の特定のスタック フレームの概念を公開します。 |
IDataModelScriptDebugVariableSetEnumerator | スクリプト プロバイダーは、このインターフェイスを実装して、一連の変数を公開します。 このセットは、関数へのパラメーターのセット、ローカル変数のセット、または特定のスコープ内の変数のセットを表します。 正確な意味は、インターフェイスの取得方法によって異なります。 |
IDataModelScriptDebugBreakpoint | スクリプト プロバイダーは、このインターフェイスを実装して、スクリプト内の特定のブレークポイントの概念と制御を公開します。 |
IDataModelScriptDebugBreakpointEnumerator | スクリプト プロバイダーはこれを実装して、スクリプト内に現在存在するすべてのブレークポイントを列挙します (有効かどうかに関係なく)。 |
一般的な管理インターフェイスは次のとおりです。
Interface | 説明 |
---|---|
IDataModelScriptProvider | スクリプト プロバイダーが実装すべき必須のコア インターフェイス。 データ モデル マネージャーのスクリプト マネージャー部分に登録されることで、特定の種類のスクリプトのプロバイダーのサポートをアドバタイズし、特定のファイル拡張子に対して登録するインターフェイスです |
IDataModelScript | プロバイダーによって管理されている特定のスクリプトの抽象化。 読み込みや編集対象の各スクリプトには、個別の IDataModelScript インスタンスがあります |
IDataModelScriptClient | スクリプト プロバイダーが、ユーザー インターフェイスに情報を通信するために使用するクライアント インターフェイス。 スクリプト プロバイダーでは、このインターフェイスは実装されません。 スクリプト プロバイダーを使用するデータ モデルをホストするアプリケーションでは実装されます。 スクリプト プロバイダーは、スクリプト クライアントのメソッドを呼び出して、状態やエラーなどを報告します。 |
IDataModelScriptHostContext | スクリプト プロバイダーが、スクリプトの内容のコンテナーとして使用するホスト インターフェイスです。 スクリプトの内容が、デバッガー アプリケーションのオブジェクト モデルに対して実行する操作以外にどのように表示されるかは、具体的なデバッグ ホストにゆだねられています。 このインターフェイスによって、スクリプト プロバイダーは、コンテンツを配置する場所に関する情報を取得できます。 |
IDataModelScriptTemplate | スクリプト プロバイダーは、ユーザーがスクリプトを作成するための開始点として機能する 1 つ以上のテンプレートを提供できます。 組み込みのエディターを提供するデバッガー アプリケーションは、このインターフェイスを使用することで、プロバイダーによってアドバタイズされたテンプレート コンテンツで新しいスクリプトを事前に入力できます。 |
IDataModelScriptTemplateEnumerator | スクリプト プロバイダーが、自身のサポートするすべてのテンプレートをアドバタイズするために使用する列挙子インターフェイス。 |
IDataModelNameBinder | 名前バインダー - コンテキスト内の名前を値に関連付けることができるオブジェクト。 名前バインダーは、たとえば "foo.bar" という式がある場合に、オブジェクト "foo" のコンテキストで名前 "bar" をバインドして、それに対する値や参照を生成できます。 通常、名前バインダーはスクリプト プロバイダーによって実装されるのではなく、既定のバインダーがデータ モデルから取得されて、スクリプト プロバイダーによって使用されます。 |
スクリプトをデバッグ可能にする: IDataModelScriptDebug
デバッグ可能なスクリプトは、IDataModelScript を実装する同じコンポーネント上に IDataModelScriptDebug インターフェイスが存在する場合に、この機能を示します。 デバッグ ホストまたはデータ モデルをホストするデバッガー アプリケーションによるこのインターフェイスのクエリは、デバッグ機能の存在を示します。
IDataModelScriptDebug インターフェイスは次のように定義されています。
DECLARE_INTERFACE_(IDataModelScriptDebug, IUnknown)
{
STDMETHOD_(ScriptDebugState, GetDebugState)() PURE;
STDMETHOD(GetCurrentPosition)(_Out_ ScriptDebugPosition *currentPosition, _Out_opt_ ScriptDebugPosition *positionSpanEnd, _Out_opt_ BSTR *lineText) PURE;
STDMETHOD(GetStack)(_COM_Outptr_ IDataModelScriptDebugStack **stack) PURE;
STDMETHOD(SetBreakpoint)(_In_ ULONG linePosition, _In_ ULONG columnPosition, _COM_Outptr_ IDataModelScriptDebugBreakpoint **breakpoint) PURE;
STDMETHOD(FindBreakpointById)(_In_ ULONG64 breakpointId, _COM_Outptr_ IDataModelScriptDebugBreakpoint **breakpoint) PURE;
STDMETHOD(EnumerateBreakpoints)(_COM_Outptr_ IDataModelScriptDebugBreakpointEnumerator **breakpointEnum) PURE;
STDMETHOD(GetEventFilter)(_In_ ScriptDebugEventFilter eventFilter, _Out_ bool *isBreakEnabled) PURE;
STDMETHOD(SetEventFilter)(_In_ ScriptDebugEventFilter eventFilter, _In_ bool isBreakEnabled) PURE;
STDMETHOD(StartDebugging)(_In_ IDataModelScriptDebugClient *debugClient) PURE;
STDMETHOD(StopDebugging)(_In_ IDataModelScriptDebugClient *debugClient) PURE;
}
GetDebugState メソッドは、スクリプトの現在の状態 (実行中かどうかなど) を返します。 状態は、ScriptDebugState 列挙内の値によって定義されます。
GetCurrentPosition' メソッドは、スクリプト内の現在位置を返します。 これは、スクリプトがデバッガーに分割され、GetScriptState の呼び出しによって ScriptDebugBreak が返される場合にのみ呼び出されます。 このメソッドの他の呼び出しは無効であり、失敗します。
GetStack メソッドは、中断位置にある現在の呼び出し履歴を取得します。 このメソッドは、スクリプトがデバッガーに分割されている場合にのみ呼び出されます。
SetBreakpoint メソッドは、スクリプト内にブレークポイントを設定します。 実装は、適切なコード位置に進むには、入力された行と列の位置を自由に調整できます。 ブレークポイントが配置された実際の行番号と列番号は、返された IDataModelScriptDebugBreakpoint インターフェイスのメソッド呼び出しによって取得できます。
SetBreakpoint メソッドを使用してスクリプト内に作成された各ブレークポイントには、実装によって一意識別子 (64 ビット符号なし整数) が割り当てられます。 FindBreakpointById メソッドは、特定の識別子からブレークポイントへのインターフェイスを取得するために使用されます。
EnumerateBreakpoints メソッドは、特定のスクリプト内で設定されているすべてのブレークポイントを列挙できる列挙子を返します。
GetEventFilter メソッドは、特定のイベントについて "break on event" が有効になっているかどうかを返します。 "break on event" が発生する可能性のあるイベントは、ScriptDebugEventFilter 列挙体のメンバーによって記述されます。
SetEventFilter メソッドは、ScriptDebugEventFilter 列挙体のメンバーによって定義されている特定のイベントの "break on event" 動作を変更します。 使用可能なすべてのイベント (およびこの列挙体の説明) の一覧は、GetEventFilter メソッドのドキュメントを参照してください。
StartDebugging メソッドは、特定のスクリプトのデバッガーを "オン" にします。 デバッグを開始しても、実行の中断やステップ実行はアクティブに行われません。 スクリプトをデバッグ可能にするだけで、クライアントがデバッグ インターフェイスと通信するためのインターフェイスのセットが提供されます。
StopDebugging メソッドは、デバッグを停止するクライアントによって呼び出されます。 このメソッド呼び出しは、StartDebugging が正常に行われた後の任意の時点で行うことができます (たとえば、中断中、スクリプトの実行中など)。呼び出しを行うと、すぐにすべてのデバッグ アクティビティが停止され、状態がリセットされた後、StartDebugging が呼び出されます。
デバッグ インターフェイス: IDataModelScriptDebugClient
スクリプト デバッグに関するインターフェイスを提供するデバッグ ホストまたはデバッガー アプリケーションでは、スクリプトのデバッグ インターフェイスで StartDebugging メソッドを使用して、スクリプト デバッガーに IDataModelScriptDebugClient インターフェイスの実装を提供する必要があります。
IDataModelScriptDebugClient は、デバッグ イベントが渡され、制御がスクリプト実行エンジンからデバッガー インターフェイスに渡される通信チャネルです。 これは次のように定義されています。
DECLARE_INTERFACE_(IDataModelScriptDebugClient, IUnknown)
{
STDMETHOD(NotifyDebugEvent)(_In_ ScriptDebugEventInformation *pEventInfo, _In_ IDataModelScript *pScript, _In_opt_ IModelObject *pEventDataObject, _Inout_ ScriptExecutionKind *resumeEventKind) PURE;
}
スクリプト デバッガーに中断するイベントが発生すると、デバッグ コード自体が NotifyDebugEvent メソッドを介してインターフェイスを呼び出します。 このメソッドは、同期的です。 インターフェイスがイベントから戻るまで、スクリプトの実行は再開されません。 スクリプト デバッガーの定義は単純であることを目的としています。処理を必要とする入れ子になったイベントはまったくありません。 デバッグ イベントは、ScriptDebugEventInformation と呼ばれるバリアント レコードによって定義されます。 有効なイベント情報のフィールドは、主に DebugEvent メンバーによって定義されます。 ScriptDebugEvent 列挙型のメンバーによって記述されたイベントの種類を定義します。
呼び出し履歴: IDataModelScriptDebugStack
スクリプト デバッガーに中断するイベントが発生すると、デバッグ インターフェイスは中断場所の呼び出し履歴を取得します。 これは、GetStack メソッドを使用して行われます。 このようなスタックは、以下に示すように定義されている IDataModelScriptDebugStack を介して表されます。
スタック全体が複数のスクリプトや複数のスクリプト プロバイダーにまたがる場合があることに注意してください。 特定のスクリプトのデバッグ インターフェイスで GetStack メソッドの 1 回の呼び出しから返される呼び出し履歴は、そのスクリプトの境界内の呼び出し履歴のセグメントのみを返します。 同じプロバイダーの 2 つのスクリプトが対話する場合、スクリプト デバッグ エンジンが複数のスクリプト コンテキストにまたがる呼び出し履歴を取得できる可能性は十分にあります。 GetStack メソッドは、別のスクリプト内にある部分の履歴は返しません。 代わりに、このような状況を検出できる場合、スクリプトの境界フレームであるスタック フレームは、そのスタック フレーム上の IsTransitionPoint メソッドと GetTransition メソッドの実装によって、自身を遷移フレームとしてマークする必要があります。 デバッガー インターフェイスは、存在する複数のスタック セグメントからスタック全体を結合する必要があります。
この方法で遷移を実装するか、デバッグ インターフェイスでローカル変数、パラメーター、ブレークポイント、およびその他のスクリプト固有のコンストラクトに関する問い合わせを間違ったスクリプト コンテキストに誘導することが不可欠です。 これにより、デバッガー インターフェイスで未定義の動作が発生します。
DECLARE_INTERFACE_(IDataModelScriptDebugStack, IUnknown)
{
STDMETHOD_(ULONG64, GetFrameCount)() PURE;
STDMETHOD(GetStackFrame)(_In_ ULONG64 frameNumber, _COM_Outptr_ IDataModelScriptDebugStackFrame **stackFrame) PURE;
}
GetFrameCount メソッドは、呼び出し履歴のこのセグメント内のスタック フレームの数を返します。 プロバイダーが異なるスクリプト コンテキストまたは異なるプロバイダーのフレームを検出できる場合は、このスタック セグメントへのエントリ フレームに IsTransitionPoint メソッドと GetTransition メソッドを実装することで、呼び出し元にこれを示す必要があります。
GetStackFrame は、スタック セグメントから特定のスタック フレームを取得します。 呼び出し履歴には、0 から始まるインデックス作成システムがあります。中断イベントが発生した現在のスタック フレームはフレーム 0 です。 現在のメソッドの呼び出し元はフレーム 1 です (以下同様)。
破損時の状態の調査: IDataModelScriptDebugStackFrame
スクリプト デバッガーに分割されたときの呼び出し履歴の特定のフレームは、中断が発生したスタック セグメントを表す IDataModelScriptDebugStack インターフェイスの GetStackFrame メソッドの呼び出しを介して取得できます。 このフレームを表すために返される IDataModelScriptDebugStackFrame インターフェイスは、次のように定義されます。
DECLARE_INTERFACE_(IDataModelScriptDebugStackFrame, IUnknown)
{
STDMETHOD(GetName)(_Out_ BSTR *name) PURE;
STDMETHOD(GetPosition)(_Out_ ScriptDebugPosition *position, _Out_opt_ ScriptDebugPosition *positionSpanEnd, _Out_opt_ BSTR *lineText) PURE;
STDMETHOD(IsTransitionPoint)(_Out_ bool *isTransitionPoint) PURE;
STDMETHOD(GetTransition)(_COM_Outptr_ IDataModelScript **transitionScript, _Out_ bool *isTransitionContiguous) PURE;
STDMETHOD(Evaluate)(_In_ PCWSTR pwszExpression, _COM_Outptr_ IModelObject **ppResult) PURE;
STDMETHOD(EnumerateLocals)(_COM_Outptr_ IDataModelScriptDebugVariableSetEnumerator **variablesEnum) PURE;
STDMETHOD(EnumerateArguments)(_COM_Outptr_ IDataModelScriptDebugVariableSetEnumerator **variablesEnum) PURE;
}
GetName メソッドは、このフレームの表示名 (関数名など) を返します。 このような名前は、デバッガー インターフェイスでユーザーに表示されるスタック バックトレース内に表示されます。
GetPosition メソッドは、スタック フレームによって表されるスクリプト内の位置を返します。 このメソッドは、スクリプトがこのフレームが含まれているスタックによって表される中断内にある場合にのみ呼び出されます。 このフレーム内の行と列の位置は常に返されます。 デバッガーがスクリプト内の "実行位置" のスパンを返すことができる場合は、positionSpanEnd 引数で終了位置を返すことができます。 デバッガーがこれを実行できない場合は、スパン エンドの行と列の値 (要求された場合) を 0 に設定する必要があります。
IDataModelScriptDebugStack インターフェイスは、呼び出し履歴のセグメント (1 つのスクリプトのコンテキスト内に含まれる呼び出し履歴の部分) を表します。 デバッガーがスクリプト間 (またはスクリプト プロバイダー間の遷移) を検出できる場合は、IsTransitionPoint メソッドを実装し、必要に応じて true または false を返すことで、これを示すことができます。 セグメントが適用されるスクリプトに入った呼び出し履歴フレームは、遷移ポイントとして扱う必要があります。 その他のフレームはすべて含まれません。
指定されたスタック フレームが IsTransition メソッドによって決定される遷移ポイントである場合 (遷移ポイントの定義については、ドキュメントを参照)、GetTransition メソッドは遷移に関する情報を返します。 特に、このメソッドは、前のスクリプト (この IDataModelScriptDebugStackFrame を含むスタック セグメントによって表されるスクリプトを呼び出したスクリプト) を返します。
Evaluate メソッドは、このメソッドが呼び出された IDataModelScriptDebugStackFrame インターフェイスによって表されるスタック フレームのコンテキストにおいて (スクリプト プロバイダーの言語の) 式を評価します。 式の評価の結果は、スクリプト プロバイダーから IModelObject としてマーシャリングする必要があります。 デバッガーが中断状態にある間は、結果として得られる IModelObject のプロパティとその他のコンストラクトをすべて取得できる必要があります。
EnumerateLocals メソッドは、このメソッドが呼び出された IDataModelScriptDebugStackFrame インターフェイスによって表されるスタック フレームのコンテキストでスコープ内にあるすべてのローカル変数の変数セット (IDataModelScriptDebugVariableSetEnumerator インターフェイスで表されます) を返します。
EnumerateArguments メソッドは、このメソッドが呼び出された IDataModelScriptDebugStackFrame インターフェイスによって表されるスタック フレームのコンテキストでスコープ内にあるすべてのローカル変数の変数セット (IDataModelScriptDebugVariableSetEnumerator インターフェイスで表されます) を返します。
変数の確認: IDataModelScriptDebugVariableSetEnumerator
デバッグ対象のスクリプト内の変数のセット (特定のスコープ内の変数、関数のローカル変数、関数の引数など) は、IDataModelScriptDebugVariableSetEnumerator インターフェイスで定義された変数セットによって表されます。
DECLARE_INTERFACE_(IDataModelScriptDebugVariableSetEnumerator, IUnknown)
{
STDMETHOD(Reset)() PURE;
STDMETHOD(GetNext)(_Out_ BSTR *variableName, _COM_Outptr_opt_ IModelObject **variableValue, _COM_Outptr_opt_result_maybenull_ IKeyStore **variableMetadata) PURE;
}
Reset メソッドは、列挙子の位置を、作成直後 (つまり、セットの最初の要素の前) にリセットします。
GetNext メソッドは、列挙子をセット内の次の変数に移動し、変数の名前、値、およびそれに関連付けられているすべてのメタデータを返します。 列挙子がセットの末尾に達した場合は、エラー E_BOUNDS が返されます。 E_BOUNDS マーカーが GetNext メソッドから返されると、介入する Reset 呼び出しが行われなければ、再度呼び出されたときに E_BOUNDS が生成され続けます。
ブレークポイント: IDataModelScriptDebugBreakpoint
スクリプト ブレークポイントは、特定のスクリプトのデバッグ インターフェイスで SetBreakpoint メソッドを使用して設定されます。 このようなブレークポイントは、一意の ID と、次のように定義されている IDataModelScriptDebugBreakpoint インターフェイスの実装の両方によって表されます。
DECLARE_INTERFACE_(IDataModelScriptDebugBreakpoint, IUnknown)
{
STDMETHOD_(ULONG64, GetId)() PURE;
STDMETHOD_(bool, IsEnabled)() PURE;
STDMETHOD_(void, Enable)() PURE;
STDMETHOD_(void, Disable)() PURE;
STDMETHOD_(void, Remove)() PURE;
STDMETHOD(GetPosition)(_Out_ ScriptDebugPosition *position, _Out_opt_ ScriptDebugPosition *positionSpanEnd, _Out_opt_ BSTR *lineText) PURE;
}
GetId メソッドは、スクリプト プロバイダーのデバッグ エンジンによってブレークポイントに割り当てられた一意の識別子を返します。 この識別子は、含まれるスクリプトのコンテキスト内で一意である必要があります。 ブレークポイント識別子はプロバイダーに対して一意である場合があります。ただし、これは必須ではありません。
IsEnabled メソッドは、ブレークポイントが有効になっているかどうかを返します。 無効になっているブレークポイントは引き続き存在し、スクリプトのブレークポイントの一覧に残っており、一時的に "オフ" にするだけです。 すべてのブレークポイントは、有効な状態で作成する必要があります。
Enable メソッドはブレークポイントを有効にします。 ブレークポイントが無効になっている場合、このメソッドを呼び出した後に "ブレークポイントにヒット" すると、デバッガーに中断が発生します。
Disable メソッドはブレークポイントを無効にします。 この呼び出しの後、このメソッドを呼び出した後に "ブレークポイントにヒット" してもデバッガーが中断されることはありません。 ブレークポイントがまだ存在する間は、"オフ" と見なされます。
Remove メソッドは、ブレークポイントを含むリストからブレークポイントを削除します。 このメソッドが戻った後は、ブレークポイントが意味的に存在しなくなります。 ブレークポイントを表していた IDataModelScriptDebugBreakpoint インターフェイスは、呼び出し後に孤立したと見なされます。 この呼び出しの後、リリースする以外に (正当に) できることはありません。
GetPosition メソッドは、スクリプト内のブレークポイントの位置を返します。 スクリプト デバッガーは、ブレークポイントが配置されているソース コード内の行と列を返す必要があります。 これを行うことができる場合は、positionSpanEnd 引数で定義されている終了位置を入力することで、ブレークポイントで表されるソースのスパンを返すこともできます。 デバッガーがこのスパンを生成できず、呼び出し元が要求した場合、スパンの終了位置の Line フィールドと Column フィールドは、値を指定できないことを示す 0 として入力する必要があります。
ブレークポイント列挙: IDataModelScriptDebugBreakpointEnumerator
スクリプト プロバイダーがデバッグをサポートしている場合は、各スクリプトに関連付けられているすべてのブレークポイントを追跡し、デバッグ インターフェイスにブレークポイントを列挙できる必要もあります。 ブレークポイントの列挙子は、特定のスクリプトのデバッグ インターフェイスの EnumerateBreakpoints メソッドを使用して取得され、次のように定義されます。
DECLARE_INTERFACE_(IDataModelScriptDebugBreakpointEnumerator, IUnknown)
{
STDMETHOD(Reset)() PURE;
STDMETHOD(GetNext)(_COM_Outptr_ IDataModelScriptDebugBreakpoint **breakpoint) PURE;
}
Reset メソッドは、列挙子が作成された直後、つまり最初に列挙されたブレークポイントの前の位置に列挙子の位置をリセットします。
GetNext メソッドは、列挙子を列挙する次のブレークポイントに移動し、そのブレークポイントの IDataModelScriptDebugBreakpoint インターフェイスを返します。 列挙子が列挙体の末尾に達した場合は、E_BOUNDS を返します。 E_BOUNDS エラーが生成されると、Reset メソッドの呼び出しが間に入っていない限り、GetNext メソッドの後続の呼び出しは引き続き E_BOUNDS を生成します。
関連項目
このトピックは、C++ からアクセスできるインターフェイス、それらを使用して C++ ベースのデバッガー拡張機能を構築する方法、および C++ データ モデル拡張機能から他のデータ モデル構造 (JavaScript や NatVis など) を利用する方法を説明するシリーズの一部です。
Debugger Data Model C++ のインターフェイス
Debugger Data Model C++ のオブジェクト