Scripting de C++ del modelo de datos del depurador
En este tema se describe cómo usar el scripting C++ del modelo de datos del depurador de C++ del modelo de datos del depurador para admitir la automatización con el motor del depurador mediante scripting.
Administración de scripts en el modelo de datos del depurador
Además del rol del Administrador de modelos de datos como autoridad central en la creación y extensibilidad de objetos, también es responsable de la administración de un concepto abstracto de scripts. Desde la perspectiva de la parte administrador de scripts del Administrador de modelos de datos, un script es algo que puede cargarse, descargarse y depurarse dinámicamente por un proveedor para ampliar o proporcionar una nueva funcionalidad al modelo de datos.
Un proveedor de scripts es un componente que une un lenguaje (por ejemplo, NatVis, JavaScript, etc.) al modelo de datos. Registra una o varias extensiones de archivo (por ejemplo: ". NatVis", ".js") que controla el proveedor, lo que permite a un cliente del depurador o una interfaz de usuario permitir la carga de archivos de script con esa extensión determinada por delegación al proveedor.
The Core Script Manager: IDataModelScriptManager
La interfaz principal del administrador de scripts se define de la siguiente manera.
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;
}
El método GetDefaultNameBinder devuelve el enlazador de nombres de script predeterminado del modelo de datos. Un enlazador de nombres es un componente que resuelve un nombre dentro del contexto de un objeto. Por ejemplo, dada la expresión "foo.bar", se llama a un enlazador de nombres para resolver la barra de nombres en el contexto del objeto foo. El enlazador devuelto aquí sigue un conjunto de reglas predeterminadas para el modelo de datos. Los proveedores de scripts pueden usar este enlazador para proporcionar coherencia en la resolución de nombres entre proveedores.
El método RegisterScriptProvider informa al modelo de datos de que existe un nuevo proveedor de scripts que es capaz de establecer un nuevo lenguaje en el modelo de datos. Cuando se llama a este método, el administrador de scripts volverá a llamar inmediatamente al proveedor de scripts especificado y consultará las propiedades de los scripts que administra. Si ya hay un proveedor registrado en el nombre o la extensión de archivo que indica el proveedor de scripts especificado, se producirá un error en este método. Solo se puede registrar un único proveedor de scripts como controlador para un nombre o extensión de archivo determinado.
Anular el registroScriptProvider
El método UnregisterScriptProvider deshace una llamada al método RegisterScriptProvider. El nombre y la extensión de archivo proporcionados por el proveedor de scripts con contraseña ya no se asociarán a él. Es importante tener en cuenta que puede haber un número significativo de referencias COM pendientes al proveedor de scripts incluso después de anular el registro. Este método solo impide la carga o creación de scripts del tipo que administra el proveedor de scripts especificado. Si un script cargado por ese proveedor sigue cargado o ha manipulado el modelo de objetos del depurador (o modelo de datos), es posible que esas manipulaciones sigan teniendo referencias al script. Puede haber modelos de datos, métodos u objetos que hagan referencia directamente a construcciones en el script. Un proveedor de scripts debe estar preparado para tratarlo.
El método FindProviderForScriptType busca en el administrador de scripts un proveedor que tenga una cadena de tipo de script como se indica en este método. Si no se encuentra uno, se producirá un error en este método; de lo contrario, este proveedor de scripts se devolverá al autor de la llamada.
El método EnumerateScriptProviders devolverá un enumerador que enumerará todos los proveedores de scripts registrados con el administrador de scripts a través de una llamada anterior al método RegisterScriptProvider.
Enumeración del proveedor de scripts: IDataModelScriptProviderEnumerator
El método EnumerateScriptProviders devolverá un enumerador de la forma siguiente:
DECLARE_INTERFACE_(IDataModelScriptProviderEnumerator, IUnknown)
{
STDMETHOD(Reset)() PURE;
STDMETHOD(GetNext)(_COM_Outptr_ IDataModelScriptProvider **provider) PURE;
}
El método Reset moverá el enumerador a la posición en la que estaba antes de devolver el primer elemento.
El método GetNext moverá el enumerador hacia delante un elemento y devolverá el proveedor de scripts que se encuentra en ese elemento. Cuando el enumerador alcanza el final de la enumeración, se devolverá E_BOUNDS. Una llamada al método GetNext después de recibir este error seguirá devolviendo E_BOUNDS indefinidamente.
Interfaces de host de C++ del modelo de datos del depurador para scripting
Rol del host en scripting
El host de depuración expone una serie de interfaces de nivel muy bajo para comprender la naturaleza del sistema de tipos de sus destinos de depuración, evaluar expresiones en el lenguaje de sus destinos de depuración, etc. Normalmente, no tiene en cuenta las construcciones de nivel superior, como el scripting. Esto se deja en la aplicación del depurador general o en las extensiones que proporcionan estas funcionalidades. Sin embargo, hay una excepción a esto. Cualquier host de depuración que quiera participar en la experiencia de scripting general que ofrece el modelo de datos debe implementar algunas interfaces sencillas para proporcionar contextos a scripts. En efecto, el host de depuración está en el control de dónde quiere que el entorno de scripting coloque funciones y otra funcionalidad proporcionada por el script dentro del espacio de nombres del modelo de datos. La participación en este proceso permite al host permitir (o no) el uso de estas funciones en, por ejemplo, su evaluador de expresiones. Las interfaces implicadas desde la perspectiva del host son:
Interfaz | Descripción |
---|---|
IDebugHostScriptHost | Interfaz que indica la capacidad del host de depuración para participar en el entorno de scripting. Esta interfaz permite la creación de contextos que informan a los motores de scripting de dónde colocar objetos. |
IDataModelScriptHostContext | Interfaz de host que usa el proveedor de scripts como contenedor para el contenido del script. El modo en que el contenido de una superficie de script que no sea las manipulaciones que realiza en el modelo de objetos de la aplicación del depurador es hasta el host de depuración determinado. Esta interfaz permite al proveedor de scripts obtener información sobre dónde colocar su contenido. Consulte Interfaces de scripting de C++ del modelo de datos más adelante en este tema para obtener más información. |
Host de script del host de depuración: IDebugHostScriptHost
La interfaz IDebugHostScriptHost es la interfaz que usa un proveedor de scripts para obtener un contexto del host de depuración de un script recién creado. Este contexto incluye un objeto (proporcionado por el host de depuración) donde el proveedor de scripts puede colocar los puentes entre el modelo de datos y el entorno de scripting. Por ejemplo, estos puentes pueden ser métodos de modelo de datos que invocan funciones de script. Esto permite que un llamador del lado del modelo de datos invoque los métodos de script mediante el uso del método Call en la interfaz IModelMethod.
La interfaz IDebugHostScriptHost se define de la siguiente manera.
DECLARE_INTERFACE_(IDebugHostScriptHost, IUnknown)
{
STDMETHOD(CreateContext)(_In_ IDataModelScript* script, _COM_Outptr_ IDataModelScriptHostContext** scriptContext) PURE;
}
Un proveedor de scripts llama al método CreateContext para crear un nuevo contexto en el que colocar el contenido del script. Este contexto se representa mediante la interfaz IDataModelScriptHostContext descrita en detalle en la página Interfaces de scripting de C++ del modelo de datos.
Interfaces de scripting de C++ del modelo de datos del depurador
Scripting e interfaces de script
La arquitectura general del modelo de datos permite a un tercero definir un puente entre algún lenguaje y el modelo de objetos del modelo de datos. Normalmente, el lenguaje que se va a enlazar es un lenguaje de scripting, ya que el entorno del modelo de datos es muy dinámico. Un componente que define e implementa este puente entre un lenguaje y el modelo de objetos del modelo de datos se denomina proveedor de scripts. Cuando se inicializa, un proveedor de scripts se registra con la parte del administrador de scripts del administrador de modelos de datos y cualquier interfaz que administre la extensibilidad permitirá posteriormente la edición, carga, descarga y posiblemente depuración de scripts escritos en el lenguaje que administra el proveedor de scripts.
Tenga en cuenta que las herramientas de depuración para Windows definen actualmente dos proveedores de scripts.
- El proveedor NatVis. Este proveedor se inserta dentro de DbgEng.dll y puentes entre NatVis XML y los modelos de datos, lo que permite la visualización de tipos de datos nativos o de lenguaje.
- El proveedor de JavaScript. Este proveedor se encuentra dentro de una extensión del depurador heredado: JsProvider.dll. Puente entre scripts escritos en el lenguaje JavaScript y el modelo de datos, lo que permite formas arbitrarias de control y extensibilidad del depurador.
Se pueden escribir nuevos proveedores que puenten otros lenguajes (por ejemplo, Python, etc.) al modelo de datos. Esto se encapsularía actualmente en extensiones de depurador heredadas con fines de carga. El propio proveedor de scripts debe minimizar la dependencia con interfaces de motor heredadas y solo debe usar las API del modelo de datos siempre que sea posible. Esto permitirá que el proveedor se haga portátil a otros entornos con una facilidad significativamente mayor.
Hay dos clases de interfaces relacionadas con proveedores de scripts. La primera clase de interfaces es para la administración general de proveedores de scripts y los scripts que administran. La segunda clase de interfaces es para admitir la depuración de scripts. Aunque la compatibilidad con el primer conjunto es obligatoria, la compatibilidad con el segundo es opcional y puede que no tenga sentido para todos los proveedores.
Las interfaces de administración general son:
Interfaz | Descripción |
---|---|
IDataModelScriptProvider | Interfaz principal que debe implementar un proveedor de scripts. Esta es la interfaz que se registra con la parte del administrador de scripts del administrador de modelos de datos para anunciar la compatibilidad del proveedor con un tipo determinado de script y registrarse en una extensión de archivo determinada. |
IDataModelScript | Abstracción de un script determinado administrado por el proveedor. Cada script que se carga o se edita tiene una instancia IDataModelScript independiente |
IDataModelScriptClient | Interfaz de cliente que usa el proveedor de scripts para comunicar información a una interfaz de usuario. Los proveedores de scripts no implementan esta interfaz. La aplicación que hospeda el modelo de datos que desea usar los proveedores de scripts sí lo hace. Un proveedor de scripts llamará a los métodos del cliente de script para notificar el estado, los errores, etc. |
IDataModelScriptHostContext | Interfaz de host que usa el proveedor de scripts como contenedor para el contenido del script. El modo en que el contenido de una superficie de script que no sea las manipulaciones que realiza en el modelo de objetos de la aplicación del depurador es hasta el host de depuración determinado. Esta interfaz permite al proveedor de scripts obtener información sobre dónde colocar su contenido. |
IDataModelScriptTemplate | Los proveedores de scripts pueden proporcionar una o varias plantillas que sirven como puntos de partida para que los usuarios creen scripts. Una aplicación del depurador que proporciona un editor integrado puede rellenar previamente nuevos scripts con contenido de plantilla como lo anuncia el proveedor a través de esta interfaz. |
IDataModelScriptTemplateEnumerator | Interfaz de enumerador que el proveedor de scripts implementa para anunciar todas las distintas plantillas que admite. |
IDataModelNameBinder | Un enlazador de nombres: un objeto que puede asociar un nombre en un contexto con un valor. Para una expresión determinada como "foo.bar", un enlazador de nombres puede enlazar el nombre "bar" en el contexto del objeto "foo" y generar un valor o referencia a él. Los enlazadores de nombres no suelen implementarse mediante un proveedor de scripts; en su lugar, el enlazador predeterminado se puede adquirir desde el modelo de datos y usarlo por el proveedor de scripts. |
Las interfaces de depuración son:
Interfaz | Descripción |
---|---|
IDataModelScriptDebug | La interfaz principal que un proveedor de scripts debe proporcionar para que un script sea depurable. La clase de implementación de la interfaz IDataModelScript debe consultarInterface para IDataModelScriptDebug si el script es depurable. |
IDataModelScriptDebugClient | La interfaz de usuario que desea proporcionar la funcionalidad de depuración de scripts implementa la interfaz IDataModelScriptDebugClient. El proveedor de scripts utiliza esta interfaz para pasar información de depuración hacia adelante y hacia delante (por ejemplo: eventos que se producen, puntos de interrupción, etc....) |
IDataModelScriptDebugStack | El proveedor de scripts implementa esta interfaz para exponer la noción de una pila de llamadas al depurador de scripts. |
IDataModelScriptDebugStackFrame | El proveedor de scripts implementa esta interfaz para exponer la noción de un marco de pila determinado dentro de la pila de llamadas. |
IDataModelScriptDebugVariableSetEnumerator | El proveedor de scripts implementa esta interfaz para exponer un conjunto de variables. Este conjunto puede representar el conjunto de parámetros en una función, el conjunto de variables locales o el conjunto de variables dentro de un ámbito determinado. El significado exacto depende de cómo se adquirió la interfaz. |
IDataModelScriptDebugBreakpoint | El proveedor de scripts implementa esta interfaz para exponer la noción y el control de un punto de interrupción determinado dentro del script. |
IDataModelScriptDebugBreakpointEnumerator | El proveedor de scripts implementa esto para enumerar todos los puntos de interrupción que existen actualmente en el script (tanto si están habilitados como no). |
El proveedor de scripts principal: IDataModelScriptProvider
Cualquier extensión que quiera ser un proveedor de scripts debe proporcionar una implementación de la interfaz IDataModelScriptProvider y registrarlo con la parte del administrador de scripts del administrador de modelos de datos a través del método RegisterScriptProvider. Esta interfaz principal que se debe implementar se define de la siguiente manera.
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;
}
El método GetName devuelve el nombre del tipo de scripts (o idioma de) que el proveedor administra como una cadena asignada a través del método SysAllocString. El autor de la llamada es responsable de liberar la cadena devuelta a través de SysFreeString. Algunos ejemplos de cadenas que se pueden devolver de este método son "JavaScript" o "NatVis". Es probable que la cadena devuelta aparezca en la interfaz de usuario de la aplicación del depurador que hospeda el modelo de datos. No se pueden devolver dos proveedores de scripts con el mismo nombre (sin distinción entre mayúsculas y minúsculas).
El método GetExtension devuelve la extensión de archivo para los scripts administrados por este proveedor (sin el punto) como una cadena asignada a través del método SysAllocString. La aplicación del depurador que hospeda el modelo de datos (con compatibilidad con scripting) delegará la apertura de archivos de script con esta extensión al proveedor de scripts. El autor de la llamada es responsable de liberar la cadena devuelta a través de SysFreeString. Algunos ejemplos de cadenas que se pueden devolver de este método son "js" o "NatVis".
Se llama al método CreateScript para crear un nuevo script. El proveedor de scripts debe devolver un script nuevo y vacío representado por la interfaz IDataModelScript devuelta siempre que se llame a este método. Tenga en cuenta que se llama a este método independientemente de si una interfaz de usuario está creando un nuevo script en blanco para su edición por parte del usuario o si la aplicación del depurador está cargando un script desde el disco. El proveedor no participa en la E/S de archivos. Simplemente controla las solicitudes de la aplicación de hospedaje a través de secuencias pasadas a métodos en IDataModelScript.
El método GetDefaultTemplateContent devuelve una interfaz para el contenido de plantilla predeterminado del proveedor. Este es el contenido que el proveedor de scripts desea rellenar previamente en una ventana de edición para un script recién creado. Si el proveedor de scripts no tiene plantillas (o no tiene contenido de plantilla designado como contenido predeterminado), el proveedor de scripts puede devolver E_NOTIMPL de este método.
El método EnumerateTemplates devuelve un enumerador que es capaz de enumerar la variedad de plantillas proporcionadas por el proveedor de scripts. El contenido de la plantilla es lo que el proveedor de scripts quiere "rellenar previamente" en una ventana de edición al crear un nuevo script. Si se admiten varias plantillas diferentes, esas plantillas se pueden denominar (por ejemplo: "Script imperativo", "Script de extensión") y la aplicación del depurador que hospeda el modelo de datos puede elegir cómo presentar las "plantillas" al usuario.
Interfaz de script principal: IDataModelScript
La interfaz principal que administra un script individual implementado por el proveedor es la interfaz IDataModelScript. Se devuelve un componente que implementa esta interfaz cuando el cliente desea crear un nuevo script en blanco y llama al método CreateScript en IDataModelScriptProvider.
Cada script creado por el proveedor debe estar en un silo independiente. Un script no debe ser capaz de afectar a otro script, excepto a través de la interacción explícita con objetos externos a través del modelo de datos. Dos scripts, por ejemplo, pueden extender algún tipo o concepto (por ejemplo, la noción del depurador de lo que es un proceso). Después, cualquier script puede acceder a los campos del otro a través del objeto de proceso externo.
La interfaz se define de la siguiente manera.
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;
}
El método GetName devuelve el nombre del script como una cadena asignada a través de la función SysAllocString. Si el script aún no tiene un nombre, el método debe devolver un BSTR nulo. No debería fallar en esta circunstancia. Si el nombre del script se cambia explícitamente a través de una llamada al método Rename, el método GetName debe devolver el nombre recién asignado.
El método Rename asigna un nuevo nombre al script. Es responsabilidad de la implementación del script guardar este nombre y devolverlo en cualquier llamada al método GetName. A menudo se llama cuando una interfaz de usuario elige Guardar como script en un nuevo nombre. Tenga en cuenta que cambiar el nombre del script puede afectar a dónde elige la aplicación de hospedaje proyectar el contenido del script.
El cliente llama al método Populate para cambiar o sincronizar el "contenido" del script. Se trata de la notificación que se realiza al proveedor de scripts de que el código del script ha cambiado. Es importante tener en cuenta que este método no provoca la ejecución del script ni los cambios en ninguno de los objetos que manipula el script. Esto es simplemente una notificación al proveedor de scripts de que el contenido del script ha cambiado para que pueda sincronizar su propio estado interno.
El método Execute ejecuta el contenido del script según lo dictado por la última llamada a Populate correcta y modifica el modelo de objetos del depurador según ese contenido. Si el lenguaje (o el proveedor de scripts) define una "función principal", una que el autor desea llamar al hacer clic en un botón "Ejecutar script" imaginario en una interfaz de usuario, no se llama a dicha "función principal" durante una operación execute. La operación Execute solo se puede considerar para realizar manipulaciones de inicialización y modelo de objetos (por ejemplo: ejecutar código raíz y configurar puntos de extensibilidad).
El método Unlink deshace la operación Execute. Las manipulaciones o puntos de extensibilidad del modelo de objetos establecidos durante la ejecución del script se deshaten. Después de una operación de desvinculación, el script se puede volver a ejecutar a través de una llamada a Execute o se puede liberar.
El método IsInvocable devuelve si el script es invocable o no, es decir, si tiene una "función principal" definida por su lenguaje o proveedor. Esta "función principal" es conceptualmente algo que el autor del script querría llamar si se presionase un botón imaginario "Ejecutar script" en una interfaz de usuario.
Si el script tiene una "función principal" que está pensada para ejecutarse desde una invocación de interfaz de usuario, indica tal a través de una devolución verdadera del método IsInvocable. A continuación, la interfaz de usuario puede llamar al método InvokeMain para "invocar" realmente el script. Tenga en cuenta que esto es distinto de Execute , que ejecuta todo el código raíz y une el script al espacio de nombres del host subyacente.
**El cliente de script: IDataModelScriptClient **
Una aplicación que hospeda el modelo de datos que desea administrar scripts y tener una interfaz de usuario (ya sea gráfica o de consola) en torno a esta noción implementa la interfaz IDataModelScriptClient. Esta interfaz se pasa a cualquier proveedor de scripts durante la ejecución, la invocación o un script para pasar información de errores y eventos a la interfaz de usuario.
La interfaz IDataModelScriptClient se define de la siguiente manera.
DECLARE_INTERFACE_(IDataModelScriptClient, IUnknown)
{
STDMETHOD(ReportError)(_In_ ErrorClass errClass, _In_ HRESULT hrFail, _In_opt_ PCWSTR message, _In_ ULONG line, _In_ ULONG position) PURE;
}
Si se produce un error durante la ejecución o invocación del script, el proveedor de scripts llama al método ReportError para notificar a la interfaz de usuario el error.
Contexto de host de un script: IDataModelScriptHostContext
El host de depuración tiene cierta influencia sobre cómo y dónde proyecta el contenido del script del modelo de datos. Se espera que cada script pida al host un contexto en el que colocar puentes al script (por ejemplo: objetos de función a los que se puede llamar, etc.). Este contexto se recupera mediante una llamada al método CreateContext en IDebugHostScriptHost y la obtención de un objeto IDataModelScriptHostContext.
La interfaz IDataModelScriptHostContext se define de la siguiente manera.
DECLARE_INTERFACE_(IDataModelScriptHostContext, IUnknown)
{
STDMETHOD(NotifyScriptChange)(_In_ IDataModelScript* script, _In_ ScriptChangeKind changeKind) PURE;
STDMETHOD(GetNamespaceObject)(_COM_Outptr_ IModelObject** namespaceObject) PURE;
}
Es necesario que un proveedor de scripts notifique al host de depuración tras ciertas operaciones que se producen con una llamada de método al método NotifyScriptChange en el contexto asociado. Estas operaciones se definen como miembros de la enumeración ScriptChangeKind.
El método GetNamespaceObject devuelve un objeto en el que el proveedor de scripts puede colocar los puentes entre el modelo de datos y el script. Es aquí, por ejemplo, que el proveedor de scripts podría colocar objetos de método de modelo de datos (interfaces IModelMethod boxed en IModelObject) cuya implementación llama a funciones con nombre correspondientes en el script.
Plantillas para scripts recién creados: IDataModelScriptTemplate
Los proveedores de scripts que quieran presentar contenido rellenado previamente para nuevos scripts (por ejemplo: para ayudar a los usuarios a escribir scripts en una interfaz de usuario del depurador) pueden hacerlo proporcionando una o varias plantillas de script. Estas plantillas son componentes que implementan la interfaz IDataModelScriptTemplate y se devuelven a través del método GetDefaultTemplate o del método EnumerateTemplates en el proveedor de scripts.
La interfaz IDataModelScriptTemplate se define de la siguiente manera.
DECLARE_INTERFACE_(IDataModelScriptTemplate, IUnknown)
{
STDMETHOD(GetName)(_Out_ BSTR *templateName) PURE;
STDMETHOD(GetDescription)(_Out_ BSTR *templateDescription) PURE;
STDMETHOD(GetContent)(_COM_Outptr_ IStream **contentStream) PURE;
}
El método GetName devuelve un nombre de la plantilla. Esto puede producir un error con E_NOTIMPL si la plantilla no tiene un nombre. La plantilla predeterminada única (si existe) no es necesaria para tener un nombre. Todas las demás plantillas son. Estos nombres se pueden presentar en una interfaz de usuario como parte de un menú para seleccionar qué plantilla se va a crear.
El método GetDescription devuelve una descripción de la plantilla. Esta descripción se presentaría al usuario en interfaces más descriptivas para ayudar al usuario a comprender lo que la plantilla está diseñada para hacer. La plantilla puede devolver E_NOTIMPL de este método si no tiene una descripción.
El método GetContent devuelve el contenido (o código) de la plantilla. Esto es lo que se rellenaría previamente en la ventana de edición si un usuario ha elegido crear un nuevo script a partir de esta plantilla. La plantilla es responsable de crear (y devolver) una secuencia estándar sobre el contenido que el cliente puede extraer.
Enumeración del contenido de plantilla de un proveedor: IDataModelScriptTemplateEnumerator
Un proveedor de scripts puede proporcionar una o varias plantillas que rellenan previamente el contenido en scripts recién creados en alguna interfaz de usuario. Si se proporciona alguna de estas plantillas, el proveedor de scripts debe implementar un enumerador sobre ellas que se devuelve tras una llamada al método EnumerateTemplates.
Este enumerador es una implementación de la interfaz IDataModelScriptTemplateEnumerator y se define de la siguiente manera.
DECLARE_INTERFACE_(IDataModelScriptTemplateEnumerator, IUnknown)
{
STDMETHOD(Reset)() PURE;
STDMETHOD(GetNext)(_COM_Outptr_ IDataModelScriptTemplate **templateContent) PURE;
}
El método Reset restablece el enumerador a la posición en la que se creó por primera vez, antes de que se generara la primera plantilla.
El método GetNext mueve el enumerador a la siguiente plantilla y lo devuelve. Al final de la enumeración, el enumerador devuelve E_BOUNDS. Una vez alcanzado el marcador de E_BOUNDS, el enumerador seguirá produciendo errores E_BOUNDS indefinidamente hasta que se realice una llamada a Reset.
Resolver el significado de los nombres: IDataModelNameBinder
El modelo de datos proporciona una manera estándar para que los proveedores de scripts determinen el significado de un nombre determinado en un contexto determinado (por ejemplo: determinar qué significa la barra para foo.bar) que funcionará en una variedad de proveedores de scripts. Este mecanismo se conoce como enlazador de nombres y se representa mediante la interfaz IDataModelNameBinder. Este enlazador encapsula un conjunto de reglas sobre cómo se resuelve el nombre y cómo tratar con la resolución de conflictos donde se define un nombre varias veces en un objeto. Parte de estas reglas incluyen cosas como cómo se resuelve un nombre proyectado (uno agregado por un modelo de datos) con un nombre nativo (uno en el sistema de tipos del lenguaje que se está depurando).
Para proporcionar un grado de coherencia entre los proveedores de scripts, el administrador de scripts del modelo de datos proporciona un enlazador de nombres predeterminado. Este enlazador de nombres predeterminado se puede adquirir a través de una llamada al método GetDefaultNameBinder en la interfaz IDataModelScriptManager. La interfaz del enlazador de nombres se define de la siguiente manera.
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;
}
El método BindValue realiza el equivalente de contextObject.name en el objeto especificado según un conjunto de reglas de enlace. El resultado de este enlace es un valor. Como valor, el proveedor de scripts subyacente no puede usar el valor para volver a realizar la asignación al nombre.
El método BindReference es similar a BindValue en que también realiza el equivalente de contextObject.name en el objeto especificado según un conjunto de reglas de enlace. Sin embargo, el resultado del enlace de este método es una referencia en lugar de un valor. Como referencia, el proveedor de scripts puede utilizar la referencia para volver a realizar la asignación al nombre.
El método EnumerateValues enumera el conjunto de nombres y valores que se enlazarán con el objeto según las reglas del método BindValue. A diferencia de EnumerateKeys, EnumerateValues y métodos similares en IModelObject, que pueden devolver varios nombres con el mismo valor (para clases base, modelos primarios y similares), este enumerador solo devolverá el conjunto específico de nombres que se enlazará con BindValue y BindReference. Los nombres nunca se duplicarán. Tenga en cuenta que hay un costo significativamente mayor de enumerar un objeto a través del enlazador de nombres que llamar a los métodos IModelObject.
El método EnumerateReferences enumera el conjunto de nombres y las referencias a ellos que se enlazarán con el objeto según las reglas del método BindReference. A diferencia de EnumerateKeys, EnumerateValues y métodos similares en IModelObject, que pueden devolver varios nombres con el mismo valor (para clases base, modelos primarios y similares), este enumerador solo devolverá el conjunto específico de nombres que se enlazará con BindValue y BindReference. Los nombres nunca se duplicarán. Tenga en cuenta que hay un costo significativamente mayor de enumerar un objeto a través del enlazador de nombres que llamar a los métodos IModelObject.
Interfaces de depuración de script de C++ del modelo de datos del depurador
La infraestructura de los proveedores de scripts del modelo de datos también proporciona un concepto sobre la depuración de scripts. Cualquier script que desee exponer las funcionalidades de depuración al host de depuración y a la aplicación del depurador que hospeda el modelo de datos puede hacerlo al tener scripts depurables implementar la interfaz IDataModelScriptDebug además de la interfaz IDataModelScriptScript. La presencia de esta interfaz en el script indica a la infraestructura que se puede depurar.
Aunque la interfaz IDataModelScriptDebug es el punto de partida para obtener acceso a las funcionalidades de depuración de un proveedor de scripts, se une a un conjunto de otras interfaces para proporcionar funcionalidades generales de depuración.
Las interfaces de depuración son:
Interfaz | Descripción |
---|---|
IDataModelScriptDebug | Interfaz principal que un proveedor de scripts debe proporcionar para poder depurar un script. La clase de implementación de la interfaz IDataModelScript debe consultarInterface para IDataModelScriptDebug si el script es depurable. |
IDataModelScriptDebugClient | La interfaz de usuario que desea proporcionar la funcionalidad de depuración de scripts implementa la interfaz IDataModelScriptDebugClient. El proveedor de scripts utiliza esta interfaz para pasar información de depuración hacia atrás y hacia delante (por ejemplo: eventos que se producen, puntos de interrupción, etc...). |
IDataModelScriptDebugStack | El proveedor de scripts implementa esta interfaz para exponer la noción de una pila de llamadas al depurador de scripts. |
IDataModelScriptDebugStackFrame | El proveedor de scripts implementa esta interfaz para exponer la noción de un marco de pila determinado dentro de la pila de llamadas. |
IDataModelScriptDebugVariableSetEnumerator | El proveedor de scripts implementa esta interfaz para exponer un conjunto de variables. Este conjunto puede representar el conjunto de parámetros en una función, el conjunto de variables locales o el conjunto de variables dentro de un ámbito determinado. El significado exacto depende de cómo se adquirió la interfaz. |
IDataModelScriptDebugBreakpoint | El proveedor de scripts implementa esta interfaz para exponer la noción y el control de un punto de interrupción determinado dentro del script. |
IDataModelScriptDebugBreakpointEnumerator | El proveedor de scripts implementa esto para enumerar todos los puntos de interrupción que existen actualmente en el script (tanto si están habilitados como no). |
Las interfaces de administración general son:
Interfaz | Descripción |
---|---|
IDataModelScriptProvider | Interfaz principal que debe implementar un proveedor de scripts. Esta es la interfaz que se registra con la parte del administrador de scripts del administrador de modelos de datos para anunciar la compatibilidad del proveedor con un tipo determinado de script y registrarse en una extensión de archivo determinada. |
IDataModelScript | Abstracción de un script determinado administrado por el proveedor. Cada script que se carga o se edita tiene una instancia IDataModelScript independiente |
IDataModelScriptClient | Interfaz de cliente que usa el proveedor de scripts para comunicar información a una interfaz de usuario. Los proveedores de scripts no implementan esta interfaz. La aplicación que hospeda el modelo de datos que desea usar los proveedores de scripts sí lo hace. Un proveedor de scripts llamará a los métodos del cliente de script para notificar el estado, los errores, etc. |
IDataModelScriptHostContext | Interfaz de host que usa el proveedor de scripts como contenedor para el contenido del script. El modo en que el contenido de una superficie de script que no sea las manipulaciones que realiza en el modelo de objetos de la aplicación del depurador es hasta el host de depuración determinado. Esta interfaz permite al proveedor de scripts obtener información sobre dónde colocar su contenido. |
IDataModelScriptTemplate | Los proveedores de scripts pueden proporcionar una o varias plantillas que sirven como puntos de partida para que los usuarios creen scripts. Una aplicación del depurador que proporciona un editor integrado puede rellenar previamente nuevos scripts con contenido de plantilla como lo anuncia el proveedor a través de esta interfaz. |
IDataModelScriptTemplateEnumerator | Interfaz de enumerador que el proveedor de scripts implementa para anunciar todas las distintas plantillas que admite. |
IDataModelNameBinder | Un enlazador de nombres: un objeto que puede asociar un nombre en un contexto con un valor. Para una expresión determinada como "foo.bar", un enlazador de nombres puede enlazar el nombre "bar" en el contexto del objeto "foo" y generar un valor o referencia a él. Los enlazadores de nombres no suelen implementarse mediante un proveedor de scripts; en su lugar, el enlazador predeterminado se puede adquirir desde el modelo de datos y usarlo por el proveedor de scripts. |
Hacer que los scripts se puedan depurar: IDataModelScriptDebug
Cualquier script que se pueda depurar indica esta funcionalidad a través de la presencia de la interfaz IDataModelScriptDebug en el mismo componente que implementa IDataModelScript. La consulta de esta interfaz por el host de depuración o la aplicación del depurador que hospeda el modelo de datos es lo que indica la presencia de la funcionalidad de depuración.
La interfaz IDataModelScriptDebug se define de la siguiente manera.
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;
}
El método GetDebugState devuelve el estado actual del script (por ejemplo, si se está ejecutando o no). El estado se define mediante un valor dentro de la enumeración ScriptDebugState.
El método GetCurrentPosition devuelve la posición actual dentro del script. Esto solo se puede llamar cuando el script se divide en el depurador donde una llamada a GetScriptState devolvería ScriptDebugBreak. Cualquier otra llamada a este método no es válida y producirá un error.
El método GetStack obtiene la pila de llamadas actual en la posición de interrupción. Solo se puede llamar a este método cuando el script se divide en el depurador.
El método SetBreakpoint establece un punto de interrupción dentro del script. Tenga en cuenta que la implementación es libre de ajustar las posiciones de línea y columna de paso a paso para avanzar a una posición de código adecuada. Los números de línea y columna reales en los que se colocó el punto de interrupción se pueden recuperar mediante llamadas de método en la interfaz IDataModelScriptDebugBreakpoint devuelta.
A cada punto de interrupción que se crea dentro del script mediante el método SetBreakpoint se le asigna un identificador único (un entero de 64 bits sin signo) por la implementación. El método FindBreakpointById se usa para obtener una interfaz al punto de interrupción de un identificador determinado.
El método EnumerateBreakpoints devuelve un enumerador capaz de enumerar todos los puntos de interrupción que se establecen dentro de un script determinado.
El método GetEventFilter devuelve si "break on event" está habilitado para un evento determinado. Los eventos que pueden provocar "interrupción en el evento" se describen mediante un miembro de la enumeración ScriptDebugEventFilter.
El método SetEventFilter cambia el comportamiento de "interrupción en el evento" de un evento determinado definido por un miembro de la enumeración ScriptDebugEventFilter. Puede encontrar una lista completa de los eventos disponibles (y una descripción de esta enumeración) en la documentación del método GetEventFilter.
El método StartDebugging "activa" el depurador para un script determinado. El acto de iniciar la depuración no provoca activamente ninguna interrupción o ejecución paso a paso. Simplemente hace que el script se pueda depurar y proporciona un conjunto de interfaces para que el cliente se comunique con la interfaz de depuración.
Un cliente llama al método StopDebugging que quiere detener la depuración. Esta llamada al método se puede realizar en cualquier momento después de que StartDebugging se haya realizado correctamente (por ejemplo, durante una interrupción, mientras se ejecuta el script, etc.). La llamada detiene inmediatamente toda la actividad de depuración y restablece el estado de nuevo a antes de llamar a StartDebugging.
Interfaz de depuración: IDataModelScriptDebugClient
El host de depuración o la aplicación del depurador que desea proporcionar una interfaz en torno a la depuración de scripts debe proporcionar una implementación de la interfaz IDataModelScriptDebugClient al depurador de scripts a través del método StartDebugging en la interfaz de depuración del script.
IDataModelScriptDebugClient es el canal de comunicación en el que se pasan los eventos de depuración y el control pasa del motor de ejecución de scripts a una interfaz del depurador. Se define como se indica a continuación.
DECLARE_INTERFACE_(IDataModelScriptDebugClient, IUnknown)
{
STDMETHOD(NotifyDebugEvent)(_In_ ScriptDebugEventInformation *pEventInfo, _In_ IDataModelScript *pScript, _In_opt_ IModelObject *pEventDataObject, _Inout_ ScriptExecutionKind *resumeEventKind) PURE;
}
Siempre que se produzca cualquier evento que se divida en el depurador de scripts, el propio código de depuración realiza una llamada a la interfaz a través del método NotifyDebugEvent. Este método es sincrónico. No se reanudará ninguna ejecución del script hasta que la interfaz vuelva del evento. La definición del depurador de scripts está pensada para ser sencilla: no hay ningún evento anidado que requiera procesamiento. Un evento de depuración se define mediante un registro variant conocido como ScriptDebugEventInformation. El miembro DebugEvent define en gran medida qué campos de la información del evento son válidos. Define el tipo de evento que se produjo tal y como se describe en un miembro de la enumeración ScriptDebugEvent.
Pila de llamadas: IDataModelScriptDebugStack
Cuando se produce un evento que se interrumpe en el depurador de scripts, la interfaz de depuración querrá recuperar la pila de llamadas para la ubicación de interrupción. Esto se realiza a través del método GetStack. Dicha pila se expresa a través de IDataModelScriptDebugStack, que se define como se indica a continuación.
Tenga en cuenta que la pila general puede abarcar varios scripts o varios proveedores de scripts. La pila de llamadas que se devuelve de una sola llamada al método GetStack en la interfaz de depuración de un script determinado solo debe devolver el segmento de la pila de llamadas dentro de los límites de ese script. Es totalmente posible que un motor de depuración de scripts pueda recuperar la pila de llamadas como abarca varios contextos de script si dos scripts del mismo proveedor interactúan. El método GetStack no debe devolver la parte de la pila que se encuentra en otro script. En su lugar, si se puede detectar esta situación, el marco de pila que es el marco de límite en el script debe marcarse como un marco de transición a través de una implementación de los métodos IsTransitionPoint y GetTransition en ese marco de pila. Se espera que la interfaz del depurador reúna la pila general de los varios segmentos de pila que existen.
Es imperativo que las transiciones se implementen de esta manera o que la interfaz de depuración pueda dirigir las consultas sobre variables locales, parámetros, puntos de interrupción y otras construcciones específicas del script al contexto de script incorrecto. Esto dará como resultado un comportamiento indefinido en la interfaz del depurador.
DECLARE_INTERFACE_(IDataModelScriptDebugStack, IUnknown)
{
STDMETHOD_(ULONG64, GetFrameCount)() PURE;
STDMETHOD(GetStackFrame)(_In_ ULONG64 frameNumber, _COM_Outptr_ IDataModelScriptDebugStackFrame **stackFrame) PURE;
}
El método GetFrameCount devuelve el número de marcos de pila de este segmento de la pila de llamadas. Si el proveedor puede detectar fotogramas en contextos de script diferentes o de proveedores diferentes, debe indicarlo al autor de la llamada mediante la implementación de los métodos IsTransitionPoint y GetTransition en el marco de entrada en este segmento de pila.
GetStackFrame obtiene un marco de pila determinado del segmento de pila. La pila de llamadas tiene un sistema de indexación de base cero: el marco de pila actual donde se produjo el evento de interrupción es el marco 0. El autor de la llamada del método actual es el marco 1 (y así sucesivamente).
Examinar el estado cuando se interrumpe: IDataModelScriptDebugStackFrame
Se puede recuperar un marco determinado de la pila de llamadas cuando se divide en el depurador de scripts a través de una llamada al método GetStackFrame en la interfaz IDataModelScriptDebugStack que representa el segmento de pila donde se produjo la interrupción. La interfaz IDataModelScriptDebugStackFrame que se devuelve para representar este fotograma se define como se indica a continuación.
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;
}
El método GetName devuelve el nombre para mostrar (por ejemplo: nombre de función) de este marco. Este nombre se mostrará dentro del retroceso de la pila presentado al usuario en la interfaz del depurador.
El método GetPosition devuelve la posición dentro del script representado por el marco de pila. Solo se puede llamar a este método cuando el script está dentro de un salto representado por la pila en la que se encuentra este marco. La posición de línea y columna dentro de este marco siempre se devuelve. Si el depurador es capaz de devolver el intervalo de la "posición de ejecución" dentro del script, se puede devolver una posición final en el argumento positionSpanEnd. Si el depurador no es capaz de esto, los valores de línea y columna del extremo del intervalo (si se solicitan) deben establecerse en cero.
La interfaz IDataModelScriptDebugStack representa un segmento de una pila de llamadas, esa parte de la pila de llamadas que se encuentra dentro del contexto de un script. Si el depurador es capaz de detectar la transición de un script a otro (o de un proveedor de scripts a otro), puede indicarlo implementando el método IsTransitionPoint y devolviendo true o false según corresponda. El marco de pila de llamadas que escribió el script en el que se aplica el segmento debe considerarse un punto de transición. El resto de fotogramas no son.
Si un marco de pila determinado es un punto de transición determinado por el método IsTransition (consulte la documentación allí para obtener una definición de puntos de transición), el método GetTransition devuelve información sobre la transición. En concreto, este método devuelve el script anterior: el que realizó una llamada al script representado por el segmento de pila que contiene este IDataModelScriptDebugStackFrame.
El método Evaluate evalúa una expresión (del lenguaje del proveedor de scripts) en el contexto del marco de pila representado por la interfaz IDataModelScriptDebugStackFrame en la que se llamó a este método. El resultado de la evaluación de expresiones debe serializarse fuera del proveedor de scripts como IModelObject. Todas las propiedades y otras construcciones en el IModelObject resultante deben poder adquirirse mientras el depurador está en un estado de interrupción.
El método EnumerateLocals devuelve un conjunto de variables (representado por una interfaz IDataModelScriptDebugVariableSetEnumerator) para todas las variables locales que están en el ámbito en el contexto del marco de pila representado por la interfaz IDataModelScriptDebugStackFrame en la que se llamó a este método.
El método EnumerateArguments devuelve un conjunto de variables (representado por una interfaz IDataModelScriptDebugVariableSetEnumerator) para todos los argumentos de función de la función a la que se llama en el marco de pila representado por la interfaz IDataModelScriptDebugStackFrame en la que se llamó a este método.
Examinar variables: IDataModelScriptDebugVariableSetEnumerator
Un conjunto de variables en el script que se está depurando (si los de un ámbito determinado, las variables locales de una función, los argumentos de una función, etc.) se representan mediante un conjunto de variables definido a través de la interfaz 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;
}
El método Reset restablece la posición del enumerador en donde estaba inmediatamente después de la creación, es decir, antes del primer elemento del conjunto.
El método GetNext mueve el enumerador a la siguiente variable del conjunto y devuelve el nombre, el valor y los metadatos asociados a ella. Si el enumerador ha alcanzado el final del conjunto, se devuelve el error E_BOUNDS. Una vez que se haya devuelto el marcador de E_BOUNDS desde el método GetNext, seguirá produciendo E_BOUNDS cuando se llame de nuevo a menos que se realice una llamada reset intermedia.
Puntos de interrupción: IDataModelScriptDebugBreakpoint
Los puntos de interrupción de script se establecen a través del método SetBreakpoint en la interfaz de depuración de un script determinado. Estos puntos de interrupción se representan mediante un identificador único y una implementación de la interfaz IDataModelScriptDebugBreakpoint, que se define como se indica a continuación.
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;
}
El método GetId devuelve el identificador único asignado por el motor de depuración del proveedor de scripts al punto de interrupción. Este identificador debe ser único en el contexto del script contenedor. El identificador del punto de interrupción puede ser único para el proveedor; sin embargo, eso no es necesario.
El método IsEnabled devuelve si el punto de interrupción está habilitado o no. Todavía existe un punto de interrupción deshabilitado y todavía está en la lista de puntos de interrupción del script, sino que simplemente se "desactiva" temporalmente. Todos los puntos de interrupción deben crearse en el estado habilitado.
El método Enable habilita el punto de interrupción. Si el punto de interrupción se deshabilitó, "alcanzar el punto de interrupción" después de llamar a este método provocará una interrupción en el depurador.
El método Disable deshabilita el punto de interrupción. Después de esta llamada, "alcanzar el punto de interrupción" después de llamar a este método no se interrumpirá en el depurador. El punto de interrupción, mientras sigue presente, se considera "desactivado".
El método Remove quita el punto de interrupción de su lista contenedora. El punto de interrupción ya no existe semánticamente después de que este método devuelva. La interfaz IDataModelScriptDebugBreakpoint que representa el punto de interrupción se considera huérfana después de la llamada. Nada más puede (legalmente) hacerse con él después de esta llamada que no sea liberarlo.
El método GetPosition devuelve la posición del punto de interrupción dentro del script. El depurador de script debe devolver la línea y la columna dentro del código fuente donde se encuentra el punto de interrupción. Si es capaz de hacerlo, también puede devolver un intervalo de origen representado por el punto de interrupción rellenando una posición final definida por el argumento positionSpanEnd. Si el depurador no es capaz de generar este intervalo y el autor de la llamada lo solicita, los campos Línea y Columna de la posición final del intervalo deben rellenarse como cero que indica que no se pueden proporcionar los valores.
Enumeración de punto de interrupción: IDataModelScriptDebugBreakpointEnumerator
Si un proveedor de scripts admite la depuración, también debe realizar un seguimiento de todos los puntos de interrupción asociados a cada script y poder enumerar esos puntos de interrupción en la interfaz de depuración. El enumerador para puntos de interrupción se adquiere a través del método EnumerateBreakpoints en la interfaz de depuración de un script determinado y se define de la siguiente manera.
DECLARE_INTERFACE_(IDataModelScriptDebugBreakpointEnumerator, IUnknown)
{
STDMETHOD(Reset)() PURE;
STDMETHOD(GetNext)(_COM_Outptr_ IDataModelScriptDebugBreakpoint **breakpoint) PURE;
}
El método Reset restablece la posición del enumerador a donde estaba justo después de crear el enumerador, es decir, antes del primer punto de interrupción enumerado.
El método GetNext mueve el enumerador hacia delante al siguiente punto de interrupción que se va a enumerar y devuelve la interfaz IDataModelScriptDebugBreakpoint para ese punto de interrupción. Si el enumerador ha llegado al final de la enumeración, devuelve E_BOUNDS. Una vez que se haya producido el error de E_BOUNDS, las llamadas posteriores al método GetNext seguirán produciendo E_BOUNDS a menos que se haya realizado una llamada intermedia al método Reset.
Vea también
Este tema forma parte de una serie que describe las interfaces accesibles desde C++, cómo usarlas para compilar una extensión del depurador basada en C++ y cómo usar otras construcciones de modelo de datos (por ejemplo, JavaScript o NatVis) desde una extensión de modelo de datos de C++.
Información general sobre el modelo de datos del depurador de C++
Interfaces de C++ del modelo de datos del depurador
Objetos C++ del modelo de datos del depurador
Interfaces adicionales del modelo de datos del depurador de C++