Поделиться через


Скрипты C++ модели данных отладчика

В этом разделе описывается использование скриптов модели данных отладчика C++ Модели данных отладчика C++ для поддержки автоматизации с подсистемой отладчика с использованием скриптов.

Управление скриптами в модели данных отладчика

Помимо роли диспетчера моделей данных в качестве центрального центра по созданию и расширяемости объектов, он также отвечает за управление абстрактной концепцией скриптов. С точки зрения части диспетчера моделей данных, скрипт может динамически загружаться, выгружать и потенциально отлаживаться поставщиком для расширения или предоставления новых функций модели данных.

Поставщик скриптов — это компонент, который связывает язык (например, NatVis, JavaScript и т. д.) с моделью данных. Он регистрирует одно или несколько расширений файлов (например, ". 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

Метод GetDefaultNameBinder возвращает связыватель имени скрипта модели данных по умолчанию. Связыватель имен — это компонент, который разрешает имя в контексте объекта . Например, учитывая выражение "foo.bar", связыватель имен вызывается для разрешения строки имен в контексте объекта foo. Возвращаемый здесь связыватель следует набору правил по умолчанию для модели данных. Поставщики скриптов могут использовать этот связыватель для обеспечения согласованности разрешения имен между поставщиками.

RegisterScriptProvider

Метод RegisterScriptProvider информирует модель данных о том, что существует новый поставщик скриптов, который способен обеспечить подключение нового языка к модели данных. При вызове этого метода диспетчер скриптов немедленно вызовет заданный поставщик скриптов и запросит свойства скриптов, которыми он управляет. Если поставщик уже зарегистрирован под именем или расширением файла, которое указывает данный поставщик скриптов, этот метод завершится ошибкой. Только один поставщик скриптов может быть зарегистрирован в качестве обработчика для определенного имени или расширения файла.

Отмена регистрацииScriptProvider

Метод UnregisterScriptProvider отменяет вызов метода RegisterScriptProvider. Имя и расширение файла, предоставленные поставщиком неустраченных скриптов, больше не будут связаны с ним. Важно отметить, что даже после отмены регистрации может существовать значительное количество необработанных ссылок COM на поставщик скриптов. Этот метод предотвращает загрузку и создание скриптов только того типа, которым управляет данный поставщик скриптов. Если скрипт, загруженный этим поставщиком, по-прежнему загружен или управляет объектной моделью отладчика (или моделью данных), эти манипуляции могут по-прежнему иметь ссылки на скрипт. Могут существовать модели данных, методы или объекты, которые напрямую ссылаться на конструкции в скрипте. Поставщик скриптов должен быть готов к этому.

FindProviderForScriptType

Метод FindProviderForScriptType выполняет поиск в диспетчере скриптов поставщика, который имеет строку типа скрипта, как указано в этом методе. Если его не удается найти, этот метод завершится ошибкой; В противном случае такой поставщик скрипта будет возвращен вызывающей объекту.

EnumerateScriptProviders

Метод EnumerateScriptProviders возвращает перечислитель, который перечисляет каждый поставщик скриптов, зарегистрированный в диспетчере сценариев с помощью предварительного вызова метода RegisterScriptProvider.

Перечисление поставщика скриптов: IDataModelScriptProviderEnumerator

Метод EnumerateScriptProviders вернет перечислитель следующей формы:

DECLARE_INTERFACE_(IDataModelScriptProviderEnumerator, IUnknown)
{
    STDMETHOD(Reset)() PURE;
    STDMETHOD(GetNext)(_COM_Outptr_ IDataModelScriptProvider **provider) PURE;
}

Сброс

Метод Reset переместит перечислитель в положение, в который он находился до возврата первого элемента.

Getnext

Метод GetNext переместит перечислитель вперед на один элемент и вернет поставщик скрипта, который находится в этом элементе. Когда перечислитель достигает конца перечисления, возвращается E_BOUNDS. Вызов метода GetNext после получения этой ошибки будет продолжать возвращать E_BOUNDS бесконечно.

Интерфейсы узла C++ модели данных отладчика для создания скриптов

Роль узла в скриптах

Узел отладки предоставляет ряд интерфейсов очень низкого уровня для понимания характера системы типов своих целевых объектов отладки, оценки выражений на языке целевых объектов отладки и т. д. Как правило, он не заботится о конструкциях более высокого уровня, таких как скрипты. Это остается за общим приложением отладчика или расширениями, которые предоставляют эти возможности. Однако есть исключение из этого. Любой узел отладки, который хочет участвовать в общих сценариях, предоставляемых моделью данных, должен реализовать несколько простых интерфейсов для предоставления контекстов скриптам. По сути, узел отладки управляет тем, где среда сценариев будет размещать функции и другие функции, предоставляемые скриптом, в пространстве имен модели данных. Участие в этом процессе позволяет узлу разрешить (или не использовать) такие функции, например, в его вычислителя выражений. Ниже перечислены интерфейсы, задействованные с точки зрения узла.

Интерфейс Описание
IDebugHostScriptHost Интерфейс, указывающий возможность узла отладки принимать участие в среде сценариев. Этот интерфейс позволяет создавать контексты, которые информируют обработчики сценариев о расположении объектов.
IDataModelScriptHostContext Интерфейс узла, используемый поставщиком скрипта в качестве контейнера для содержимого скрипта. Содержимое скрипта, отличное от операций, которые он выполняет с объектной моделью приложения отладчика, определяется конкретным узлом отладки. Этот интерфейс позволяет поставщику скриптов получать сведения о расположении его содержимого. Дополнительные сведения см. в разделе Интерфейсы сценариев C++ модели данных далее в этом разделе.

Узел скриптов узла отладки: IDebugHostScriptHost

Интерфейс IDebugHostScriptHost — это интерфейс, используемый поставщиком скриптов для получения контекста от узла отладки для созданного скрипта. Этот контекст включает объект (предоставляемый узлом отладки), где поставщик скриптов может размещать любые мосты между моделью данных и средой скриптов. Например, такие мосты могут быть методами модели данных, которые вызывают функции скриптов. Это позволяет вызывающей стороне модели данных вызывать методы скрипта, используя метод Call в интерфейсе IModelMethod.

Интерфейс IDebugHostScriptHost определяется следующим образом.

DECLARE_INTERFACE_(IDebugHostScriptHost, IUnknown)
{
    STDMETHOD(CreateContext)(_In_ IDataModelScript* script, _COM_Outptr_ IDataModelScriptHostContext** scriptContext) PURE;
}

CreateContext

Метод CreateContext вызывается поставщиком скрипта для создания нового контекста, в котором будет размещаться содержимое скрипта. Такой контекст представлен интерфейсом IDataModelScriptHostContext, подробно описанным на странице Интерфейсы скриптов модели данных C++.

Интерфейсы скриптов C++ для модели данных отладчика

Скрипты и интерфейсы скриптов

Общая архитектура модели данных позволяет третьей стороне определить мост между тем или иным языком и объектной моделью модели данных. Как правило, связываемый язык является языком сценариев, так как среда модели данных очень динамическая. Компонент, который определяет и реализует этот мост между языком и объектной моделью модели данных, называется поставщиком скриптов. При инициализации поставщик скриптов регистрирует себя в части диспетчера моделей данных, и любой интерфейс, который управляет расширяемостью, впоследствии позволит редактировать, загружать, выгружать и, возможно, отладку скриптов, написанных на языке, которым управляет поставщик скриптов.

Обратите внимание, что средства отладки для Windows в настоящее время определяют два поставщика скриптов.

  • Поставщик NatVis. Этот поставщик внедряется в DbgEng.dll и мосты между NatVis XML и моделями данных, что позволяет визуализации собственных и языковых типов данных.
  • Поставщик JavaScript. Этот поставщик содержится в устаревшем расширении отладчика: JsProvider.dll. Он выполняет мост между скриптами, написанными на языке JavaScript, и моделью данных, обеспечивая произвольные формы управления отладчиком и расширяемость.

Можно написать новые поставщики, которые будут соединять другие языки (например, Python и т. д.) с моделью данных. В настоящее время они будут инкапсулированы в устаревшие расширения отладчика для загрузки. Сам поставщик скриптов должен свести к минимуму зависимость с устаревшими интерфейсами подсистемы и использовать API модели данных только там, где это возможно. Это значительно упрощает перенос поставщика в другие среды.

Существует два класса интерфейсов, связанных с поставщиками скриптов. Первый класс интерфейсов предназначен для общего управления поставщиками скриптов и скриптами, которыми они управляют. Второй класс интерфейсов предназначен для поддержки отладки скриптов. Хотя поддержка первого набора является обязательной, поддержка второго является необязательной и может не подходить для каждого поставщика.

Общие интерфейсы управления:

Интерфейс Описание
IDataModelScriptProvider Основной интерфейс, который должен реализовать поставщик скриптов. Это интерфейс, который регистрируется в диспетчере сценариев диспетчера моделей данных для объявления поддержки поставщиком определенного типа скрипта и регистрации в определенном расширении файла.
IDataModelScript Абстракция определенного скрипта, которым управляет поставщик. Каждый скрипт, который загружается или редактируется, имеет отдельный экземпляр IDataModelScript.
IDataModelScriptClient Клиентский интерфейс, используемый поставщиком скриптов для передачи информации в пользовательский интерфейс. Поставщики скриптов не реализуют этот интерфейс. Это делает приложение, в котором размещается модель данных, которая хочет использовать поставщиков скриптов. Поставщик скриптов вызывает методы клиента скрипта, чтобы сообщить о состоянии, ошибках и т. д.
IDataModelScriptHostContext Интерфейс узла, используемый поставщиком скрипта в качестве контейнера для содержимого скрипта. Содержимое скрипта, отличное от операций, которые он выполняет с объектной моделью приложения отладчика, определяется конкретным узлом отладки. Этот интерфейс позволяет поставщику скриптов получать сведения о расположении его содержимого.
IDataModelScriptTemplate Поставщики скриптов могут предоставлять один или несколько шаблонов, которые служат отправной точкой для создания скриптов пользователями. Приложение отладчика, предоставляющее встроенный редактор, может предварительно заполнять новые скрипты содержимым шаблона, объявленным поставщиком через этот интерфейс.
IDataModelScriptTemplateEnumerator Интерфейс перечислителя, который реализует поставщик скриптов для объявления всех поддерживаемых шаблонов.
IDataModelNameBinder Связыватель имен — объект, который может связать имя в контексте со значением. Для данного выражения, например "foo.bar", связыватель имени может привязать имя "bar" в контексте объекта "foo" и создать значение или ссылку на него. Связыватели имен обычно не реализуются поставщиком скриптов; вместо этого связыватель по умолчанию может быть получен из модели данных и использоваться поставщиком скриптов

Интерфейсы отладки:

Интерфейс Описание
IDataModelScriptDebug Основной интерфейс, который должен предоставить поставщик скриптов, чтобы сделать скрипт отлаживаемым. Класс реализации интерфейса IDataModelScript должен выполнять queryInterface для IDataModelScriptDebug, если скрипт является отлаживаемым.
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

Метод GetName возвращает имя типа скриптов (или языка), которыми управляет поставщик, в виде строки, выделенной с помощью метода SysAllocString. Вызывающий объект отвечает за освобождение возвращаемой строки с помощью SysFreeString. Примерами строк, которые могут быть возвращены из этого метода, являются "JavaScript" или "NatVis". Возвращаемая строка, скорее всего, появится в пользовательском интерфейсе приложения отладчика, в котором размещена модель данных. Ни один из двух поставщиков скриптов не может возвращать одно и то же имя (без учета регистра).

GetExtension

Метод GetExtension возвращает расширение файла для скриптов, управляемых этим поставщиком (без точки), в виде строки, выделенной с помощью метода SysAllocString. Приложение отладчика, в котором размещена модель данных (с поддержкой сценариев), делегируют открытие файлов скриптов с этим расширением поставщику скриптов. Вызывающий объект отвечает за освобождение возвращаемой строки с помощью SysFreeString. Примерами строк, которые могут быть возвращены из этого метода, являются "js" или "NatVis".

CreateScript

Метод CreateScript вызывается для создания нового скрипта. При каждом вызове этого метода поставщик скриптов должен возвращать новый и пустой скрипт, представленный возвращенным интерфейсом IDataModelScript. Обратите внимание, что этот метод вызывается независимо от того, создает ли пользовательский интерфейс новый пустой скрипт для редактирования пользователем или приложение отладчика загружает скрипт с диска. Поставщик не участвует в файловом вводе-выводе. Он просто обрабатывает запросы от приложения размещения через потоки, передаваемые в методы iDataModelScript.

GetDefaultTemplateContent

Метод GetDefaultTemplateContent возвращает интерфейс для содержимого шаблона по умолчанию поставщика. Это содержимое, которое поставщик скриптов должен предварительно заполнить в окне редактирования для только что созданного скрипта. Если у поставщика скриптов нет шаблонов (или нет содержимого шаблона, которое обозначено как содержимое по умолчанию), поставщик скриптов может вернуть E_NOTIMPL из этого метода.

EnumerateTemplates

Метод EnumerateTemplates возвращает перечислитель, который может перечислять различные шаблоны, предоставляемые поставщиком скрипта. Содержимое шаблона — это то, что поставщик скриптов хочет предварительно заполнить в окне редактирования при создании нового скрипта. Если поддерживается несколько разных шаблонов, эти шаблоны могут быть названы (например, "Императивный скрипт", "Скрипт расширения"), и приложение отладчика, в котором размещена модель данных, может выбрать способ представления "шаблонов" пользователю.

Интерфейс основного скрипта: IDataModelScript

Интерфейс main, который управляет отдельным скриптом, реализованным поставщиком, — это интерфейс IDataModelScript. Компонент, реализующий этот интерфейс, возвращается, когда клиент хочет создать новый пустой скрипт и вызывает метод CreateScript в IDataModelScriptProvider.

Каждый скрипт, созданный поставщиком, должен находиться в независимом хранилище. Один скрипт не должен влиять на другой сценарий, кроме явного взаимодействия с внешними объектами через модель данных. Например, два скрипта могут расширять некоторый тип или концепцию (например, представление отладчика о том, что такое процесс). Затем любой сценарий может получить доступ к полям друг друга через объект внешнего процесса.

Интерфейс определяется следующим образом.

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

Метод GetName возвращает имя скрипта в виде выделенной строки с помощью функции SysAllocString. Если у скрипта еще нет имени, метод должен возвращать значение null BSTR. Он не должен провалиться в этих обстоятельствах. Если скрипт явно переименован с помощью вызова метода Rename, метод GetName должен вернуть только что назначенное имя.

Переименование

Метод Rename присваивает скрипту новое имя. Реализация скрипта отвечает за сохранение этого имени и его возврат при любом вызове метода GetName. Это часто вызывается, когда пользовательский интерфейс выбирает команду Сохранить как скрипт с новым именем. Обратите внимание, что переименование скрипта может повлиять на то, где размещающее приложение выбирает проецировать содержимое скрипта.

Заполнить

Метод Заполнение вызывается клиентом для изменения или синхронизации "содержимого" скрипта. Поставщику скрипта отправляется уведомление об изменении кода скрипта. Важно отметить, что этот метод не приводит к выполнению скрипта или изменению каких-либо объектов, которыми управляет скрипт. Это просто уведомление для поставщика скрипта о том, что содержимое скрипта изменилось, чтобы он мог синхронизировать собственное внутреннее состояние.

Execute

Метод Execute выполняет содержимое скрипта в соответствии с последним успешным вызовом Заполнение и изменяет объектную модель отладчика в соответствии с этим содержимым. Если язык (или поставщик скриптов) определяет "main функцию", которую автор хотел бы вызвать при нажатии воображаемой кнопки "Выполнить скрипт" в пользовательском интерфейсе, такая "функция main" не вызывается во время операции Execute. Операцию Execute можно рассматривать только для выполнения инициализации и манипуляций с объектной моделью (например, выполнение корневого кода и настройка точек расширяемости).

Отсоединить

Метод Unlink отменяет операцию Execute. Любые манипуляции с объектной моделью или точки расширяемости, установленные во время выполнения скрипта, отменяются. После операции отмены связи скрипт может быть повторно выполнен с помощью вызова Execute или освобожден.

IsInvocable

Метод IsInvocable возвращает, является ли скрипт неизменяемым, то есть имеет ли он "функцию main", определенную языком или поставщиком. Такая "main функция" концептуально является тем, что автор сценария хотел бы вызвать, если в пользовательском интерфейсе была нажата воображаемая кнопка "Выполнить скрипт".

InvokeMain

Если скрипт содержит функцию main, которая предназначена для выполнения из вызова пользовательского интерфейса, он указывает на это с помощью истинного возврата из метода 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

Если во время выполнения или вызова скрипта возникает ошибка, поставщик скрипта вызывает метод ReportError для уведомления пользовательского интерфейса об ошибке.

Контекст узла для скрипта: IDataModelScriptHostContext

Узел отладки имеет некоторое влияние на то, как и где он проецировал содержимое скрипта модели данных. Ожидается, что каждый скрипт запрашивает у узла контекст для размещения мостов к скрипту (например, объекты функций, которые можно вызывать, и т. д.). Этот контекст извлекается путем вызова метода CreateContext в IDebugHostScriptHost и получения IDataModelScriptHostContext.

Интерфейс IDataModelScriptHostContext определяется следующим образом.

DECLARE_INTERFACE_(IDataModelScriptHostContext, IUnknown)
{
   STDMETHOD(NotifyScriptChange)(_In_ IDataModelScript* script, _In_ ScriptChangeKind changeKind) PURE;
   STDMETHOD(GetNamespaceObject)(_COM_Outptr_ IModelObject** namespaceObject) PURE;
}

NotifyScriptChange

Поставщик скриптов должен уведомлять узел отладки о выполнении определенных операций с вызовом метода NotifyScriptChange в связанном контексте. Такие операции определяются как члены перечисления ScriptChangeKind.

GetNamespaceObject

Метод GetNamespaceObject возвращает объект, в который поставщик скрипта может размещать любые мосты между моделью данных и скриптом. Например, поставщик скрипта может размещать объекты метода модели данных (интерфейсы IModelMethod, упакованные в IModelObject), реализация которых вызывает соответствующие функции в скрипте.

Шаблоны для вновь созданных скриптов: IDataModelScriptTemplate

Поставщики скриптов, которые хотят представить предварительно заполненное содержимое для новых сценариев (например, чтобы помочь пользователям писать скрипты в пользовательском интерфейсе отладчика), могут сделать это, предоставив один или несколько шаблонов скриптов. Такие шаблоны являются компонентами, которые реализуют интерфейс 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

Метод GetName возвращает имя шаблона. Это может завершиться ошибкой при E_NOTIMPL, если шаблон не имеет имени. Один шаблон по умолчанию (если таковой существует) не обязательно должен иметь имя. Все остальные шаблоны являются. Эти имена можно представить в пользовательском интерфейсе как часть меню для выбора создаваемого шаблона.

GetDescription

Метод GetDescription возвращает описание шаблона. Такое описание будет представлено пользователю в более описательных интерфейсах, чтобы помочь пользователю понять, для чего предназначен шаблон. Шаблон может возвращать E_NOTIMPL из этого метода, если у него нет описания.

GetContent

Метод GetContent возвращает содержимое (или код) шаблона. Это то, что будет предварительно заполнено в окне редактирования, если пользователь решил создать новый скрипт на основе этого шаблона. Шаблон отвечает за создание (и возврат) стандартного потока по содержимому, которое клиент может извлечь.

Перечисление содержимого шаблона поставщика: IDataModelScriptTemplateEnumerator

Поставщик скриптов может предоставить один или несколько шаблонов, которые предварительно заполняют содержимое во вновь созданные скрипты в некотором пользовательском интерфейсе. Если предоставлен какой-либо из этих шаблонов, поставщик скриптов должен реализовать перечислитель над ними, который возвращается при вызове метода EnumerateTemplates.

Такой перечислитель является реализацией интерфейса IDataModelScriptTemplateEnumerator и определяется следующим образом.

DECLARE_INTERFACE_(IDataModelScriptTemplateEnumerator, IUnknown)
{
   STDMETHOD(Reset)() PURE;
   STDMETHOD(GetNext)(_COM_Outptr_ IDataModelScriptTemplate **templateContent) PURE;
}

Сброс

Метод Reset сбрасывает перечислитель в положение, в которое он находился при его создании — до создания первого шаблона.

Getnext

Метод GetNext перемещает перечислитель в следующий шаблон и возвращает его. В конце перечисления перечислитель возвращает E_BOUNDS. После нажатия маркера E_BOUNDS перечислитель будет продолжать создавать E_BOUNDS ошибки до тех пор, пока не будет выполнен вызов Reset.

Разрешение значения имен: IDataModelNameBinder

Модель данных предоставляет поставщикам скриптов стандартный способ определения значения заданного имени в заданном контексте (например, определение того, что означает столбец для foo.bar), который будет работать с различными поставщиками скриптов. Этот механизм известен как связыватель имен и представлен интерфейсом IDataModelNameBinder. Такой связыватель инкапсулирует набор правил о том, как разрешается имя и как работать с разрешением конфликтов, когда имя определяется несколько раз в объекте. Часть этих правил включает, например, способ разрешения проецируемого имени (добавляемого моделью данных) с собственным именем (в системе типов отлаживаемого языка).

Чтобы обеспечить определенную согласованность между поставщиками скриптов, диспетчер скриптов модели данных предоставляет связыватель имен по умолчанию. Этот связыватель имен по умолчанию можно получить с помощью вызова метода GetDefaultNameBinder в интерфейсе IDataModelScriptManager. Интерфейс связывателя имен определяется следующим образом.

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

Метод BindValue выполняет эквивалент contextObject.name для заданного объекта в соответствии с набором правил привязки. Результатом этой привязки является значение. В качестве значения базовый поставщик скрипта не может использовать значение для выполнения присваивания имени.

BindReference

Метод BindReference аналогичен BindValue тем, что он также выполняет эквивалент contextObject.name для заданного объекта в соответствии с набором правил привязки. Однако результатом привязки этого метода является ссылка, а не значение. В качестве ссылки поставщик скрипта может использовать ссылку для выполнения присваивания имени.

EnumerateValues

Метод EnumerateValues перечисляет набор имен и значений, которые будут привязаны к объекту в соответствии с правилами метода BindValue. В отличие от методов EnumerateKeys, EnumerateValues и аналогичных методов в IModelObject, которые могут возвращать несколько имен с одинаковым значением (для базовых классов, родительских моделей и т. д.), этот перечислитель будет возвращать только определенный набор имен, который будет выполнять привязку с помощью BindValue и BindReference. Имена никогда не будут повторяться. Обратите внимание, что перечисление объекта с помощью связывателя имен значительно выше, чем вызов методов IModelObject.

EnumerateReferences

Метод EnumerateReferences перечисляет набор имен и ссылок на них, которые привязываются к объекту в соответствии с правилами метода BindReference. В отличие от методов EnumerateKeys, EnumerateValues и аналогичных методов в IModelObject, которые могут возвращать несколько имен с одинаковым значением (для базовых классов, родительских моделей и т. д.), этот перечислитель будет возвращать только определенный набор имен, который будет выполнять привязку с помощью BindValue и BindReference. Имена никогда не будут повторяться. Обратите внимание, что перечисление объекта с помощью связывателя имен значительно выше, чем вызов методов IModelObject.

Интерфейсы отладки скрипта C++ для модели данных отладчика

Инфраструктура для поставщиков скриптов в модели данных также предоставляет концепцию отладки скриптов. Любой сценарий, который хочет предоставить возможности отладки для узла отладки и приложения отладчика, в котором размещена модель данных, может сделать это, если отлаживаемые скрипты реализуют интерфейс IDataModelScriptDebug в дополнение к интерфейсу IDataModelScript. Наличие этого интерфейса в скрипте указывает инфраструктуре, что он является отлаживаемым.

Хотя интерфейс IDataModelScriptDebug является отправной точкой для получения доступа к возможностям отладки поставщика скриптов, он объединяется набором других интерфейсов для предоставления общих возможностей отладки.

Интерфейсы отладки:

Интерфейс Описание
IDataModelScriptDebug Основной интерфейс, который должен предоставить поставщик скриптов, чтобы сделать скрипт отлаживаемым. Класс реализации интерфейса IDataModelScript должен выполнять queryInterface для IDataModelScriptDebug, если скрипт является отлаживаемым.
IDataModelScriptDebugClient Пользовательский интерфейс, который хочет предоставить возможность отладки скриптов, реализует интерфейс IDataModelScriptDebugClient. Поставщик скриптов использует этот интерфейс для передачи отладочной информации взад и вперед (например, происходящие события, точки останова и т. д.).
IDataModelScriptDebugStack Поставщик скриптов реализует этот интерфейс для предоставления отладчику скриптов понятия стека вызовов.
IDataModelScriptDebugStackFrame Поставщик скриптов реализует этот интерфейс для предоставления представления о конкретном кадре стека в стеке вызовов.
IDataModelScriptDebugVariableSetEnumerator Поставщик скриптов реализует этот интерфейс для предоставления набора переменных. Этот набор может представлять набор параметров функции, набор локальных переменных или набор переменных в пределах определенного область. Точное значение зависит от способа получения интерфейса.
IDataModelScriptDebugBreakpoint Поставщик скриптов реализует этот интерфейс для предоставления представления о конкретной точке останова и управления ими в скрипте.
IDataModelScriptDebugBreakpointEnumerator Поставщик скриптов реализует это для перечисления всех точек останова, которые в настоящее время существуют в скрипте (независимо от того, включены ли они или нет).

Общие интерфейсы управления:

Интерфейс Описание
IDataModelScriptProvider Основной интерфейс, который должен реализовать поставщик скриптов. Это интерфейс, который регистрируется в диспетчере сценариев диспетчера моделей данных для объявления поддержки поставщиком определенного типа скрипта и регистрации в определенном расширении файла.
IDataModelScript Абстракция определенного скрипта, которым управляет поставщик. Каждый скрипт, который загружается или редактируется, имеет отдельный экземпляр IDataModelScript.
IDataModelScriptClient Клиентский интерфейс, используемый поставщиком скриптов для передачи информации в пользовательский интерфейс. Поставщики скриптов не реализуют этот интерфейс. Это делает приложение, в котором размещается модель данных, которая хочет использовать поставщиков скриптов. Поставщик скриптов вызывает методы клиента скрипта, чтобы сообщить о состоянии, ошибках и т. д.
IDataModelScriptHostContext Интерфейс узла, используемый поставщиком скрипта в качестве контейнера для содержимого скрипта. Содержимое скрипта, отличное от операций, которые он выполняет с объектной моделью приложения отладчика, определяется конкретным узлом отладки. Этот интерфейс позволяет поставщику скриптов получать сведения о расположении его содержимого.
IDataModelScriptTemplate Поставщики скриптов могут предоставлять один или несколько шаблонов, которые служат отправной точкой для создания скриптов пользователями. Приложение отладчика, предоставляющее встроенный редактор, может предварительно заполнять новые скрипты содержимым шаблона, объявленным поставщиком через этот интерфейс.
IDataModelScriptTemplateEnumerator Интерфейс перечислителя, который реализует поставщик скриптов для объявления всех поддерживаемых шаблонов.
IDataModelNameBinder Связыватель имен — объект, который может связать имя в контексте со значением. Для данного выражения, например "foo.bar", связыватель имени может привязать имя "bar" в контексте объекта "foo" и создать значение или ссылку на него. Связыватели имен обычно не реализуются поставщиком скриптов; вместо этого связыватель по умолчанию может быть получен из модели данных и использоваться поставщиком скрипта.

Создание отлаживаемых сценариев: IDataModelScriptDebug

Любой отлаживаемый скрипт указывает на эту возможность благодаря наличию интерфейса IDataModelScriptDebug в том же компоненте, который реализует IDataModelScript. Запрос к этому интерфейсу узла отладки или приложения отладчика, в котором размещена модель данных, указывает на наличие возможности отладки.

Интерфейс 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

Метод GetDebugState возвращает текущее состояние скрипта (например, выполняется ли он или нет). Состояние определяется значением в перечислении ScriptDebugState.

GetCurrentPosition

Метод GetCurrentPosition возвращает текущую позицию в скрипте. Он может вызываться только в том случае, если скрипт разбивается на отладчик, где вызов GetScriptState возвращает ScriptDebugBreak. Любой другой вызов этого метода недопустим и завершится ошибкой.

GetStack

Метод GetStack получает текущий стек вызовов в позиции останова. Этот метод может вызываться только в том случае, если скрипт разбит на отладчик.

SetBreakpoint

Метод SetBreakpoint задает точку останова в скрипте. Обратите внимание, что реализация может свободно настраивать позиции в строке и столбце для перехода вперед в соответствующую позицию кода. Фактические номера строк и столбцов, в которых была размещена точка останова, можно получить с помощью вызовов методов в возвращенном интерфейсе IDataModelScriptDebugBreakpoint.

FindBreakpointById

Каждой точке останова, созданной в скрипте с помощью метода SetBreakpoint, реализация присваивает уникальный идентификатор (64-разрядное целое число без знака). Метод FindBreakpointById используется для получения интерфейса к точке останова из заданного идентификатора.

Перечисление Точек останова

Метод EnumerateBreakpoints возвращает перечислитель, способный перечислить каждую точку останова, заданную в определенном скрипте.

GetEventFilter

Метод GetEventFilter возвращает значение, включено ли "прерывание события" для определенного события. События, которые могут вызвать "прерывание события", описываются членом перечисления ScriptDebugEventFilter.

SetEventFilter

Метод SetEventFilter изменяет поведение "прерывания события" для определенного события, определенного членом перечисления ScriptDebugEventFilter. Полный список доступных событий (и описание этого перечисления) можно найти в документации по методу GetEventFilter.

StartDebugging

Метод StartDebugging "включает" отладчик для определенного скрипта. Запуск отладки не приводит к прерыванию выполнения или пошаговому выполнению. Это просто делает скрипт отлаживаемым и предоставляет набор интерфейсов для взаимодействия клиента с интерфейсом отладки.

StopDebugging

Метод StopDebugging вызывается клиентом, который хочет остановить отладку. Этот вызов метода может быть выполнен в любой момент после успешного выполнения StartDebugging (например, во время перерыва, во время выполнения скрипта и т. д.). Вызов немедленно прекращает все действия отладки и сбрасывает состояние до вызова StartDebugging.

Интерфейс отладки: IDataModelScriptDebugClient

Узел отладки или приложение отладчика, которое хочет предоставить интерфейс для отладки скриптов, должно предоставить отладчику скрипта реализацию интерфейса IDataModelScriptDebugClient с помощью метода StartDebugging в интерфейсе отладки скрипта.

IDataModelScriptDebugClient — это канал связи, по которому передаются события отладки, а управление осуществляется от подсистемы выполнения скриптов до интерфейса отладчика. Он определяется следующим образом.

DECLARE_INTERFACE_(IDataModelScriptDebugClient, IUnknown)
{
   STDMETHOD(NotifyDebugEvent)(_In_ ScriptDebugEventInformation *pEventInfo, _In_ IDataModelScript *pScript, _In_opt_ IModelObject *pEventDataObject, _Inout_ ScriptExecutionKind *resumeEventKind) PURE;
}

NotifyDebugEvent

Всякий раз, когда происходит какое-либо событие, которое врывается в отладчик скрипта, сам код отладки вызывает интерфейс с помощью метода NotifyDebugEvent. Этот метод является синхронным. Выполнение скрипта не будет возобновлено до тех пор, пока интерфейс не вернется из события . Определение отладчика скрипта должно быть простым: нет абсолютно никаких вложенных событий, требующих обработки. Событие отладки определяется записью варианта, известной как ScriptDebugEventInformation. Допустимые поля в сведениях о событии в значительной степени определяются элементом DebugEvent. Он определяет тип события, которое произошло, как описано членом перечисления ScriptDebugEvent.

Стек вызовов: IDataModelScriptDebugStack

При возникновении события, которое врывается в отладчик скрипта, интерфейс отладки хочет получить стек вызовов для расположения останова. Это делается с помощью метода GetStack. Такой стек выражается через IDataModelScriptDebugStack, который определен, как показано ниже.

Обратите внимание, что общий стек может охватывать несколько скриптов и (или) несколько поставщиков скриптов. Стек вызовов, возвращаемый из одного вызова метода GetStack в интерфейсе отладки конкретного скрипта, должен возвращать только сегмент стека вызовов в пределах этого скрипта. Вполне возможно, что подсистема отладки скриптов может получить стек вызовов, так как охватывает несколько контекстов скриптов, если взаимодействуют два скрипта одного поставщика. Метод GetStack не должен возвращать часть стека, которая находится в другом сценарии. Вместо этого, если такая ситуация может быть обнаружена, кадр стека, являющийся пограничным кадром в скрипте, должен помечать себя как кадр перехода с помощью реализации методов IsTransitionPoint и GetTransition в этом кадре стека. Ожидается, что интерфейс отладчика сшет общий стек из нескольких существующих сегментов стека.

Крайне важно, чтобы переходы были реализованы таким образом, иначе интерфейс отладки мог направлять запросы о локальных переменных, параметрах, точках останова и других конструкциях сценария в неправильный контекст скрипта. Это приведет к неопределенному поведению в интерфейсе отладчика.

DECLARE_INTERFACE_(IDataModelScriptDebugStack, IUnknown)
{
   STDMETHOD_(ULONG64, GetFrameCount)() PURE;
   STDMETHOD(GetStackFrame)(_In_ ULONG64 frameNumber, _COM_Outptr_ IDataModelScriptDebugStackFrame **stackFrame) PURE;
}

GetFrameCount

Метод GetFrameCount возвращает количество кадров стека в этом сегменте стека стека. Если поставщик может обнаруживать кадры в разных контекстах скрипта или у разных поставщиков, он должен указать это вызывающему объекту путем реализации методов IsTransitionPoint и GetTransition в кадре входа в этот сегмент стека.

GetStackFrame

GetStackFrame получает определенный кадр стека из сегмента стека. Стек вызовов имеет отсчитываемую от нуля систему индексирования: текущий кадр стека, в котором произошло событие прерывания, равен кадру 0. Вызывающим объектом текущего метода является кадр 1 (и т. д.).

Проверка состояния при разрыве: IDataModelScriptDebugStackFrame

Конкретный кадр стека вызовов, разбитый на отладчик скриптов, можно получить с помощью вызова метода GetStackFrame в интерфейсе IDataModelScriptDebugStack, представляющего сегмент стека, в котором произошел разрыв. Интерфейс 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

Метод GetName возвращает отображаемое имя (например, имя функции) этого кадра. Такое имя будет отображаться в обратной трассировке стека, представленной пользователю в интерфейсе отладчика.

GetPosition

Метод GetPosition возвращает позицию в скрипте, представленном кадром стека. Этот метод может вызываться только в том случае, если скрипт находится в пределах разрыва, представленного стеком, в котором содержится этот кадр. Позиция строки и столбца внутри этого кадра всегда возвращается. Если отладчик может возвращать диапазон "позиции выполнения" в скрипте, в аргументе positionSpanEnd может быть возвращена конечная позиция. Если отладчик не поддерживает это, значения строки и столбца в конце диапазона (при необходимости) должны быть равны нулю.

IsTransitionPoint

Интерфейс IDataModelScriptDebugStack представляет сегмент стека вызовов — часть стека вызовов, которая содержится в контексте одного скрипта. Если отладчик может обнаруживать переход от одного скрипта к другому (или от одного поставщика скриптов к другому), он может указать это, реализовав метод IsTransitionPoint и возвращая значение true или false соответствующим образом. Кадр стека вызовов, который вошел в скрипт, в котором применяется сегмент, должен считаться точкой перехода. Все остальные кадры не являются.

GetTransition

Если заданный кадр стека является точкой перехода, определяемой методом IsTransition (определение точек перехода см. в документации), метод GetTransition возвращает сведения о переходе. В частности, этот метод возвращает предыдущий скрипт , который сделал вызов скрипта, представленного сегментом стека, содержащим этот IDataModelScriptDebugStackFrame.

Вычислить

Метод Evaluate вычисляет выражение (языка поставщика скриптов) в контексте кадра стека, представленного интерфейсом IDataModelScriptDebugStackFrame, в котором был вызван этот метод. Результат вычисления выражения должен быть маршалирован из поставщика скрипта как IModelObject. Свойства и другие конструкции результирующего объекта IModelObject должны быть получены, пока отладчик находится в состоянии останова.

EnumerateLocals

Метод EnumerateLocals возвращает набор переменных (представленный интерфейсом IDataModelScriptDebugVariableSetEnumerator) для всех локальных переменных, которые находятся в область в контексте кадра стека, представленного интерфейсом IDataModelScriptDebugStackFrame, для которого был вызван этот метод.

EnumerateArguments

Метод EnumerateArguments возвращает набор переменных (представленный интерфейсом IDataModelScriptDebugVariableSetEnumerator) для всех аргументов функции, вызываемой в кадре стека, представленном интерфейсом IDataModelScriptDebugStackFrame, в котором был вызван этот метод.

Просмотр переменных: 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

Метод GetNext перемещает перечислитель в следующую переменную в наборе и возвращает имя переменной, значение и все связанные с ней метаданные. Если перечислитель достиг конца набора, возвращается E_BOUNDS ошибки. После возврата маркера E_BOUNDS из метода GetNext он будет продолжать создавать E_BOUNDS при повторном вызове, если не будет выполнен промежуточный вызов Reset.

Точки останова: IDataModelScriptDebugBreakpoint

Точки останова скрипта задаются с помощью метода SetBreakpoint в интерфейсе отладки данного скрипта. Такие точки останова представлены как уникальным идентификатором, так и реализацией интерфейса 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

Метод GetId возвращает уникальный идентификатор, назначенный обработчиком отладки поставщика скриптов точке останова. Этот идентификатор должен быть уникальным в контексте содержащего скрипта. Идентификатор точки останова может быть уникальным для поставщика; однако это не требуется.

IsEnabled

Метод IsEnabled возвращает значение, указывающее, включена ли точка останова. Отключенная точка останова все еще существует и по-прежнему находится в списке точек останова для скрипта. Она просто временно "отключена". Все точки останова должны быть созданы в включенном состоянии.

Разрешить

Метод Enable включает точку останова. Если точка останова была отключена, "попадание в точку останова" после вызова этого метода приведет к разрыву в отладчике.

Отключить

Метод Disable отключает точку останова. После этого вызова "попадание в точку останова" после вызова этого метода не войдет в отладчик. Точка останова, хотя она все еще существует, считается "отключенной".

Удалить

Метод Remove удаляет точку останова из содержащегося в ней списка. Точка останова больше не существует семантически после возврата этого метода. Интерфейс IDataModelScriptDebugBreakpoint, представляющий точку останова, считается потерянным после вызова. После этого вызова с ним не может быть сделано ничего другого, кроме как освободить его.

GetPosition

Метод GetPosition возвращает позицию точки останова в скрипте. Отладчик скрипта должен возвращать строку и столбец в исходном коде, где находится точка останова. Если это возможно, он также может вернуть диапазон источника, представленный точкой останова, заполнив конечную позицию, определенную аргументом positionSpanEnd. Если отладчик не может создать этот диапазон и вызывающий объект запрашивает его, поля Строка и Столбец конечной позиции диапазона должны быть заполнены как ноль, что указывает на то, что значения не могут быть предоставлены.

Перечисление точек останова: IDataModelScriptDebugBreakpointEnumerator

Если поставщик скриптов поддерживает отладку, он также должен отслеживать все точки останова, связанные с каждым скриптом, и иметь возможность перечислять эти точки останова в интерфейсе отладки. Перечислитель для точек останова получается с помощью метода EnumerateBreakpoints в интерфейсе отладки для данного скрипта и определяется следующим образом.

DECLARE_INTERFACE_(IDataModelScriptDebugBreakpointEnumerator, IUnknown)
{
   STDMETHOD(Reset)() PURE;
   STDMETHOD(GetNext)(_COM_Outptr_ IDataModelScriptDebugBreakpoint **breakpoint) PURE;
}

Сброс

Метод Reset сбрасывает позицию перечислителя до того места, где он находился сразу после создания перечислителя, то есть до первой точки останова.

Getnext

Метод GetNext перемещает перечислитель вперед к следующей точке останова для перечисления и возвращает интерфейс IDataModelScriptDebugBreakpoint для этой точки останова. Если перечислитель достиг конца перечисления, он возвращает E_BOUNDS. После возникновения ошибки E_BOUNDS последующие вызовы метода GetNext будут продолжать вызывать E_BOUNDS, если не был выполнен промежуточный вызов метода Reset.


См. также

Этот раздел является частью серии, в которой описываются интерфейсы, доступные из C++, способы их использования для создания расширения отладчика на основе C++, а также способы использования других конструкций модели данных (например, JavaScript или NatVis) из расширения модели данных C++.

Общие сведения о модели данных отладчика C++

Интерфейсы C++ модели данных отладчика

Объекты C++ модели данных отладчика

Дополнительные интерфейсы C++ модели данных отладчика

Основные понятия модели данных отладчика C++