Script C++ do modelo de dados do depurador
Este tópico descreve como usar scripts C++ do Modelo de Dados do Depurador C++ do Modelo de Dados do Depurador para dar suporte à automação com o mecanismo de depurador usando scripts.
Gerenciamento de script no modelo de dados do depurador
Além da função do Gerenciador de Modelos de Dados como a autoridade central na criação e extensibilidade de objetos, ele também é responsável pelo gerenciamento de um conceito abstrato de scripts. Da perspectiva da parte do Gerenciador de Scripts do Gerenciador de Modelos de Dados, um script é algo que pode ser carregado dinamicamente, descarregado e potencialmente depurado por um provedor para estender ou fornecer novas funcionalidades ao modelo de dados.
Um provedor de script é um componente que conecta uma linguagem (por exemplo: NatVis, JavaScript etc...) ao modelo de dados. Ele registra uma ou mais extensões de arquivo (por exemplo: ". NatVis", ".js") que são tratados pelo provedor, permitindo que um cliente de depurador ou uma interface do usuário permita o carregamento de arquivos de script com essa extensão específica por delegação ao provedor.
O Gerenciador de Scripts Principal: IDataModelScriptManager
A interface principal do gerenciador de scripts é definida da seguinte maneira.
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;
}
O método GetDefaultNameBinder retorna o associador de nome de script padrão do modelo de dados. Um associador de nome é um componente que resolve um nome dentro do contexto de um objeto . Por exemplo, dada a expressão "foo.bar", um associador de nome é chamado para resolve a barra de nomes no contexto do objeto foo. O associador retornado aqui segue um conjunto de regras padrão para o modelo de dados. Os provedores de script podem usar esse associador para fornecer consistência na resolução de nomes entre provedores.
O método RegisterScriptProvider informa ao modelo de dados que existe um novo provedor de script que é capaz de fazer a ponte de uma nova linguagem para o modelo de dados. Quando esse método for chamado, o gerenciador de scripts chamará imediatamente de volta o provedor de script especificado e perguntará sobre as propriedades dos scripts gerenciados por ele. Se já houver um provedor registrado sob o nome ou a extensão de arquivo que o provedor de script especificado indica, esse método falhará. Somente um único provedor de script pode ser registrado como o manipulador para um nome ou extensão de arquivo específico.
O método UnregisterScriptProvider desfaz uma chamada para o método RegisterScriptProvider. O nome e a extensão de arquivo fornecidos pelo provedor de script inpassado não serão mais associados a ele. É importante observar que pode haver um número significativo de referências COM pendentes ao provedor de script mesmo após o cancelamento do registro. Esse método só impede o carregamento/criação de scripts do tipo que o provedor de script fornecido gerencia. Se um script carregado por esse provedor ainda estiver carregado ou tiver manipulado o modelo de objeto do depurador (ou modelo de dados), essas manipulações ainda poderão ter referências de volta ao script. Pode haver modelos de dados, métodos ou objetos que referenciam diretamente constructos no script. Um provedor de script deve estar preparado para lidar com isso.
O método FindProviderForScriptType pesquisa no gerenciador de scripts um provedor que tem uma cadeia de caracteres de tipo de script, conforme indicado neste método. Se não for possível encontrar, esse método falhará; caso contrário, esse provedor de script será retornado ao chamador.
O método EnumerateScriptProviders retornará um enumerador que enumerará todos os provedores de script que foram registrados com o gerenciador de scripts por meio de uma chamada anterior ao método RegisterScriptProvider.
Enumeração do provedor de script: IDataModelScriptProviderEnumerator
O método EnumerateScriptProviders retornará um enumerador do seguinte formulário:
DECLARE_INTERFACE_(IDataModelScriptProviderEnumerator, IUnknown)
{
STDMETHOD(Reset)() PURE;
STDMETHOD(GetNext)(_COM_Outptr_ IDataModelScriptProvider **provider) PURE;
}
O método Reset moverá o enumerador para a posição em que estava antes de retornar o primeiro elemento.
O método GetNext moverá o enumerador para frente um elemento e retornará o provedor de script que está nesse elemento. Quando o enumerador atingir o final da enumeração, E_BOUNDS será retornado. Chamar o método GetNext depois de receber esse erro continuará a retornar E_BOUNDS indefinidamente.
Depurar interfaces de host C++ do modelo de dados do depurador para scripts
A função do host no script
O host de depuração expõe uma série de interfaces de nível muito baixo para entender a natureza do sistema de tipos de seus destinos de depuração, avaliando expressões na linguagem de seus destinos de depuração, etc... Normalmente, ele não está preocupado com constructos de nível mais alto, como scripts. Isso é deixado para o aplicativo de depurador geral ou para extensões que fornecem esses recursos. No entanto, há uma exceção a isso. Qualquer host de depuração que queira participar da experiência geral de script oferecida pelo modelo de dados precisa implementar algumas interfaces simples para fornecer contextos aos scripts. Na verdade, o host de depuração está no controle de onde deseja que o ambiente de script coloque funções e outras funcionalidades fornecidas pelo script no namespace do modelo de dados. Estar envolvido nesse processo permite que o host permita (ou não) o uso dessas funções em, por exemplo, seu avaliador de expressão. As interfaces envolvidas da perspectiva do host aqui são:
Interface | Descrição |
---|---|
IDebugHostScriptHost | A interface que indica a capacidade do host de depuração de participar no ambiente de script. Essa interface permite a criação de contextos que informam os mecanismos de script de onde colocar objetos. |
IDataModelScriptHostContext | Uma interface de host que é usada pelo provedor de script como um contêiner para o conteúdo do script. Como o conteúdo de uma superfície de script diferente das manipulações executadas no modelo de objeto do aplicativo de depurador cabe ao host de depuração específico. Essa interface permite que o provedor de script obtenha informações sobre onde colocar seu conteúdo. Consulte Interfaces de script C++ do modelo de dados mais adiante neste tópico para obter mais informações. |
Host de script do host de depuração: IDebugHostScriptHost
A interface IDebugHostScriptHost é a interface usada por um provedor de script para obter um contexto do host de depuração para um script recém-criado. Esse contexto inclui um objeto (fornecido pelo host de depuração) em que o provedor de script pode colocar quaisquer pontes entre o modelo de dados e o ambiente de script. Essas pontes podem, por exemplo, ser métodos de modelo de dados que invocam funções de script. Isso permite que um chamador no lado do modelo de dados invoque métodos de script usando o método Call na interface IModelMethod.
A interface IDebugHostScriptHost é definida da seguinte maneira.
DECLARE_INTERFACE_(IDebugHostScriptHost, IUnknown)
{
STDMETHOD(CreateContext)(_In_ IDataModelScript* script, _COM_Outptr_ IDataModelScriptHostContext** scriptContext) PURE;
}
O método CreateContext é chamado por um provedor de script para criar um novo contexto no qual colocar o conteúdo do script. Esse contexto é representado pela interface IDataModelScriptHostContext descrita em detalhes na página Interfaces de Script C++ do Modelo de Dados.
Interfaces de script C++ do modelo de dados do depurador
Scripts e interfaces de script
A arquitetura geral do modelo de dados permite que um terceiro defina uma ponte entre alguma linguagem e o modelo de objeto do modelo de dados. Normalmente, a linguagem que está sendo colocada em ponte é uma linguagem de script, pois o ambiente do modelo de dados é muito dinâmico. Um componente que define e implementa essa ponte entre uma linguagem e o modelo de objeto do modelo de dados é chamado de provedor de script. Quando inicializado, um provedor de script se registra na parte do gerenciador de scripts do gerenciador de modelos de dados e qualquer interface que gerencia a extensibilidade permitirá posteriormente a edição, o carregamento, o descarregamento e a potencial depuração de scripts gravados no idioma que o provedor de script gerencia.
Observe que as Ferramentas de Depuração para Windows atualmente definem dois provedores de script.
- O Provedor NatVis. Esse provedor é inserido em DbgEng.dll e pontes entre o NatVis XML e os modelos de dados, permitindo a visualização de tipos de dados nativos/de linguagem.
- O Provedor JavaScript. Esse provedor está contido em uma extensão de depurador herdada: JsProvider.dll. Ele faz a ponte entre scripts escritos na linguagem JavaScript e no modelo de dados, permitindo formas arbitrárias de controle e extensibilidade do depurador.
Novos provedores podem ser gravados, o que faz a ponte entre outras linguagens (por exemplo: Python, etc...) para o modelo de dados. Isso seria encapsulado atualmente em extensões de depurador herdadas para fins de carregamento. O próprio provedor de script deve minimizar a dependência com interfaces de mecanismo herdadas e deve utilizar apenas as APIs do modelo de dados sempre que possível. Isso permitirá que o provedor seja portátil para outros ambientes com uma facilidade significativamente maior.
Há duas classes de interfaces relacionadas aos provedores de script. A primeira classe de interfaces é para o gerenciamento geral de provedores de script e os scripts que eles gerenciam. A segunda classe de interfaces é para dar suporte à depuração de script. Embora o suporte para o primeiro conjunto seja obrigatório, o suporte para o segundo é opcional e pode não fazer sentido para todos os provedores.
As interfaces gerais de gerenciamento são:
Interface | Descrição |
---|---|
IDataModelScriptProvider | A interface principal que um provedor de script deve implementar. Essa é a interface que é registrada com a parte do gerenciador de scripts do gerenciador de modelos de dados para anunciar o suporte do provedor de um tipo específico de script e registrar-se em uma extensão de arquivo específica |
IDataModelScript | Uma abstração de um script específico que está sendo gerenciado pelo provedor. Cada script carregado ou editado tem uma instância IDataModelScript separada |
IDataModelScriptClient | Uma interface do cliente que é usada pelo provedor de script para comunicar informações a uma interface do usuário. Os provedores de script não implementam essa interface. O aplicativo que hospeda o modelo de dados que deseja fazer uso de provedores de script faz. Um provedor de script chamará métodos do cliente de script para relatar status, erros etc... |
IDataModelScriptHostContext | Uma interface de host que é usada pelo provedor de script como um contêiner para o conteúdo do script. Como o conteúdo de uma superfície de script diferente das manipulações executadas no modelo de objeto do aplicativo depurador cabe ao host de depuração específico. Essa interface permite que o provedor de script obtenha informações sobre onde colocar seu conteúdo. |
IDataModelScriptTemplate | Os provedores de script podem fornecer um ou mais modelos que servem como pontos de partida para os usuários criarem scripts. Um aplicativo de depurador que fornece um editor interno pode pré-filtrar novos scripts com conteúdo de modelo conforme anunciado pelo provedor por meio dessa interface. |
IDataModelScriptTemplateEnumerator | Uma interface de enumerador que o provedor de script implementa para anunciar todos os vários modelos compatíveis. |
IDataModelNameBinder | Um associador de nome – um objeto que pode associar um nome em um contexto a um valor. Para uma determinada expressão, como "foo.bar", um associador de nome é capaz de associar o nome "bar" no contexto do objeto "foo" e produzir um valor ou referência a ele. Os associadores de nomes normalmente não são implementados por um provedor de script; em vez disso, o associador padrão pode ser adquirido do modelo de dados e usado pelo provedor de script |
As interfaces de depuração são:
Interface | Descrição |
---|---|
IDataModelScriptDebug | A interface principal que um provedor de script deve fornecer para tornar um script depurável. A classe de implementação da interface IDataModelScript deve QueryInterface para IDataModelScriptDebug se o script for depurável. |
IDataModelScriptDebugClient | A interface do usuário que deseja fornecer a capacidade de depuração de script implementa a interface IDataModelScriptDebugClient. O provedor de script utiliza essa interface para passar informações de depuração para frente e para trás (por exemplo: eventos que ocorrem, pontos de interrupção etc...) |
IDataModelScriptDebugStack | O provedor de script implementa essa interface para expor a noção de uma pilha de chamadas ao depurador de script. |
IDataModelScriptDebugStackFrame | O provedor de script implementa essa interface para expor a noção de um quadro de pilha específico dentro da pilha de chamadas. |
IDataModelScriptDebugVariableSetEnumerator | O provedor de script implementa essa interface para expor um conjunto de variáveis. Esse conjunto pode representar o conjunto de parâmetros para uma função, o conjunto de variáveis locais ou o conjunto de variáveis dentro de um escopo específico. O significado exato depende de como a interface foi adquirida. |
IDataModelScriptDebugBreakpoint | O provedor de script implementa essa interface para expor a noção e o controle de um ponto de interrupção específico dentro do script. |
IDataModelScriptDebugBreakpointEnumerator | O provedor de script implementa isso para enumerar todos os pontos de interrupção que existem atualmente no script (habilitados ou não). |
O provedor de script principal: IDataModelScriptProvider
Qualquer extensão que queira ser um provedor de script deve fornecer uma implementação da interface IDataModelScriptProvider e registrá-la na parte do gerenciador de scripts do gerenciador de modelos de dados por meio do método RegisterScriptProvider. Essa interface principal que deve ser implementada é definida da seguinte maneira.
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;
}
O método GetName retorna o nome do tipo de scripts (ou idioma de) que o provedor gerencia como uma cadeia de caracteres alocada por meio do método SysAllocString. O chamador é responsável por liberar a cadeia de caracteres retornada por meio de SysFreeString. Exemplos de cadeias de caracteres que podem ser retornadas desse método são "JavaScript" ou "NatVis". É provável que a cadeia de caracteres retornada apareça na interface do usuário do aplicativo depurador que está hospedando o modelo de dados. Nenhum provedor de script pode retornar o mesmo nome (não diferencia maiúsculas de minúsculas).
O método GetExtension retorna a extensão de arquivo para scripts gerenciados por esse provedor (sem o ponto) como uma cadeia de caracteres alocada por meio do método SysAllocString. O aplicativo de depurador que hospeda o modelo de dados (com suporte a scripts) delegará a abertura de arquivos de script com essa extensão para o provedor de script. O chamador é responsável por liberar a cadeia de caracteres retornada por meio de SysFreeString. Exemplos de cadeias de caracteres que podem ser retornadas desse método são "js" ou "NatVis".
O método CreateScript é chamado para criar um script. O provedor de script deve retornar um script novo e vazio representado pela interface IDataModelScript retornada sempre que esse método for chamado. Observe que esse método é chamado independentemente de uma interface do usuário criar um script em branco para edição pelo usuário ou se o aplicativo do depurador está carregando um script do disco. O provedor não se envolve na E/S do arquivo. Ele apenas manipula as solicitações do aplicativo de hospedagem por meio de fluxos passados para métodos em IDataModelScript.
O método GetDefaultTemplateContent retorna uma interface para o conteúdo de modelo padrão do provedor. Esse é o conteúdo que o provedor de script gostaria de preencher previamente em uma janela de edição para um script recém-criado. Se o provedor de script não tiver modelos (ou não tiver nenhum conteúdo de modelo designado como o conteúdo padrão), o provedor de script poderá retornar E_NOTIMPL desse método.
O método EnumerateTemplates retorna um enumerador que é capaz de enumerar a variedade de modelos fornecidos pelo provedor de script. O conteúdo do modelo é o que o provedor de script deseja que seja "preenchido previamente" em uma janela de edição ao criar um novo script. Se houver vários modelos diferentes com suporte, esses modelos poderão ser nomeados (por exemplo: "Script Imperativo", "Script de Extensão") e o aplicativo de depurador que hospeda o modelo de dados poderá escolher como apresentar os "modelos" ao usuário.
A interface de script principal: IDataModelScript
A interface main que gerencia um script individual implementado pelo provedor é a interface IDataModelScript. Um componente que implementa essa interface é retornado quando o cliente deseja criar um script em branco e chama o método CreateScript em IDataModelScriptProvider.
Cada script criado pelo provedor deve estar em um silo independente. Um script não deve ser capaz de afetar outro script, exceto por meio de interação explícita com objetos externos por meio do modelo de dados. Dois scripts, por exemplo, podem estender algum tipo ou conceito (por exemplo: a noção do depurador do que é um processo). Qualquer script pode acessar os campos uns dos outros por meio do objeto de processo externo.
A interface é definida da seguinte maneira.
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;
}
O método GetName retorna o nome do script como uma cadeia de caracteres alocada por meio da função SysAllocString. Se o script ainda não tiver um nome, o método deverá retornar um BSTR nulo. Não deve falhar nesta circunstância. Se o script for renomeado explicitamente por meio de uma chamada para o método Rename, o método GetName deverá retornar o nome recém-atribuído.
O método Rename atribui um novo nome ao script. É responsabilidade da implementação do script salvar esse nome e retorná-lo em qualquer chamada para o método GetName. Isso geralmente é chamado quando uma interface do usuário opta por Salvar como o script para um novo nome. Observe que renomear o script pode afetar onde o aplicativo de hospedagem opta por projetar o conteúdo do script.
O método Populate é chamado pelo cliente para alterar ou sincronizar o "conteúdo" do script. É a notificação feita ao provedor de scripts de que o código do script foi alterado. É importante observar que esse método não causa a execução do script ou alterações em nenhum dos objetos que o script manipula. Isso é apenas uma notificação para o provedor de script de que o conteúdo do script foi alterado para que ele possa sincronizar seu próprio estado interno.
O método Execute executa o conteúdo do script conforme determinado pela última chamada de Preenchimento bem-sucedida e modifica o modelo de objeto do depurador de acordo com esse conteúdo. Se a linguagem (ou o provedor de script) definir uma "função main" – aquela que o autor desejaria chamar ao clicar em um botão imaginário "Executar Script" em uma interface do usuário , essa "função main" não será chamada durante uma operação Execute. A operação Executar pode ser considerada para executar somente manipulações de inicialização e modelo de objeto (por exemplo: execução de código raiz e configuração de pontos de extensibilidade).
O método Unlink desfaz a operação Execute. Quaisquer manipulações de modelo de objeto ou pontos de extensibilidade estabelecidos durante a execução do script são desfeitos. Após uma operação Desvincular, o script pode ser executado novamente por meio de uma chamada para Executar ou pode ser liberado.
O método IsInvocable retorna se o script é invocado ou não , ou seja, se ele tem uma "função main", conforme definido por sua linguagem ou provedor. Essa "função main" é conceitualmente algo que o autor do script gostaria de chamar se um botão imaginário "Executar Script" fosse pressionado em uma interface do usuário.
Se o script tiver uma "função main" que se destina a ser executada a partir de uma invocação de interface do usuário, ele indicará isso por meio de um retorno verdadeiro do método IsInvocable. Em seguida, a interface do usuário pode chamar o método InvokeMain para realmente "invocar" o script. Observe que isso é diferente de Executar , que executa todo o código raiz e conecta o script ao namespace do host subjacente.
**O cliente de script: IDataModelScriptClient **
Um aplicativo que hospeda o modelo de dados que deseja gerenciar scripts e ter uma interface do usuário (seja gráfica ou de console) em torno dessa noção implementa a interface IDataModelScriptClient. Essa interface é passada para qualquer provedor de script durante a execução ou invocação ou um script para passar informações de erro e evento de volta para a interface do usuário.
A interface IDataModelScriptClient é definida da seguinte maneira.
DECLARE_INTERFACE_(IDataModelScriptClient, IUnknown)
{
STDMETHOD(ReportError)(_In_ ErrorClass errClass, _In_ HRESULT hrFail, _In_opt_ PCWSTR message, _In_ ULONG line, _In_ ULONG position) PURE;
}
Se ocorrer um erro durante a execução ou invocação do script, o provedor de script chamará o método ReportError para notificar a interface do usuário do erro.
O contexto do host para um script: IDataModelScriptHostContext
O host de depuração tem alguma influência sobre como e onde ele projeta o conteúdo do script do modelo de dados. Espera-se que cada script solicite ao host um contexto no qual colocar pontes para o script (por exemplo: objetos de função que podem ser chamados etc...). Esse contexto é recuperado por meio da chamada do método CreateContext em IDebugHostScriptHost e da obtenção de um IDataModelScriptHostContext.
A interface IDataModelScriptHostContext é definida da seguinte maneira.
DECLARE_INTERFACE_(IDataModelScriptHostContext, IUnknown)
{
STDMETHOD(NotifyScriptChange)(_In_ IDataModelScript* script, _In_ ScriptChangeKind changeKind) PURE;
STDMETHOD(GetNamespaceObject)(_COM_Outptr_ IModelObject** namespaceObject) PURE;
}
É necessário que um provedor de script notifique o host de depuração em determinadas operações que ocorrem com uma chamada de método para o método NotifyScriptChange no contexto associado. Essas operações são definidas como membros da enumeração ScriptChangeKind
O método GetNamespaceObject retorna um objeto no qual o provedor de script pode colocar quaisquer pontes entre o modelo de dados e o script. É aqui, por exemplo, que o provedor de script pode colocar objetos de método de modelo de dados (interfaces IModelMethod boxed em IModelObject) cuja implementação chama em funções correspondentemente nomeadas no script.
Modelos para scripts recém-criados: IDataModelScriptTemplate
Os provedores de script que desejam apresentar conteúdo pré-preenchido para novos scripts (por exemplo: para ajudar os usuários que escrevem scripts em uma interface do usuário do depurador) podem fazer isso fornecendo um ou mais modelos de script. Esses modelos são componentes que implementam a interface IDataModelScriptTemplate e são retornados por meio do método GetDefaultTemplate ou do método EnumerateTemplates no provedor de script.
A interface IDataModelScriptTemplate é definida da seguinte maneira.
DECLARE_INTERFACE_(IDataModelScriptTemplate, IUnknown)
{
STDMETHOD(GetName)(_Out_ BSTR *templateName) PURE;
STDMETHOD(GetDescription)(_Out_ BSTR *templateDescription) PURE;
STDMETHOD(GetContent)(_COM_Outptr_ IStream **contentStream) PURE;
}
O método GetName retorna um nome do modelo. Isso poderá falhar com E_NOTIMPL se o modelo não tiver um nome. O modelo padrão único (se tal existir) não é necessário para ter um nome. Todos os outros modelos são. Esses nomes podem ser apresentados em uma interface do usuário como parte de um menu para selecionar qual modelo deve ser criado.
O método GetDescription retorna uma descrição do modelo. Essa descrição seria apresentada ao usuário em interfaces mais descritivas para ajudar o usuário a entender o que o modelo foi projetado para fazer. O modelo poderá retornar E_NOTIMPL desse método se não tiver uma descrição.
O método GetContent retorna o conteúdo (ou código) do modelo. Isso é o que seria preenchido previamente na janela de edição se um usuário optar por criar um novo script com base nesse modelo. O modelo é responsável por criar (e retornar) um fluxo padrão sobre o conteúdo que o cliente pode efetuar pull.
Enumeração do conteúdo de modelo de um provedor: IDataModelScriptTemplateEnumerator
Um provedor de script pode fornecer um ou mais modelos que preencham o conteúdo em scripts recém-criados em alguma interface do usuário. Se qualquer um desses modelos for fornecido, o provedor de script deverá implementar um enumerador sobre eles que é retornado após uma chamada para o método EnumerateTemplates.
Esse enumerador é uma implementação da interface IDataModelScriptTemplateEnumerator e é definido da seguinte maneira.
DECLARE_INTERFACE_(IDataModelScriptTemplateEnumerator, IUnknown)
{
STDMETHOD(Reset)() PURE;
STDMETHOD(GetNext)(_COM_Outptr_ IDataModelScriptTemplate **templateContent) PURE;
}
O método Reset redefine o enumerador para a posição em que estava quando foi criado pela primeira vez antes do primeiro modelo ser produzido.
O método GetNext move o enumerador para o próximo modelo e o retorna. No final da enumeração, o enumerador retorna E_BOUNDS. Depois que o marcador de E_BOUNDS for atingido, o enumerador continuará a produzir erros E_BOUNDS indefinidamente até que uma chamada de redefinição seja feita.
Resolvendo o significado dos nomes: IDataModelNameBinder
O modelo de dados fornece uma maneira padrão para os provedores de script determinarem o significado de um determinado nome em um determinado contexto (por exemplo: determinar o que significa barra para foo.bar) que operará em uma variedade de provedores de script. Esse mecanismo é conhecido como um associador de nome e é representado pela interface IDataModelNameBinder. Esse associador encapsula um conjunto de regras sobre como o nome é resolvido e como lidar com a resolução de conflitos em que um nome é definido várias vezes em um objeto. Parte dessas regras inclui itens como como um nome projetado (um adicionado por um modelo de dados) é resolvido em relação a um nome nativo (um no sistema de tipos da linguagem que está sendo depurado).
Para fornecer um grau de consistência entre provedores de script, o gerenciador de scripts do modelo de dados fornece um associador de nome padrão. Esse associador de nome padrão pode ser adquirido por meio de uma chamada para o método GetDefaultNameBinder na interface IDataModelScriptManager. A interface do associador de nome é definida da seguinte maneira.
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;
}
O método BindValue executa o equivalente a contextObject.name no objeto fornecido de acordo com um conjunto de regras de associação. O resultado dessa associação é um valor. Como valor, o provedor de script subjacente não pode usar o valor para executar a atribuição de volta ao nome.
O método BindReference é semelhante a BindValue, pois também executa o equivalente a contextObject.name no objeto fornecido de acordo com um conjunto de regras de associação. No entanto, o resultado da associação desse método é uma referência em vez de um valor. Como referência, o provedor de script pode utilizar a referência para executar a atribuição de volta ao nome.
O método EnumerateValues enumera o conjunto de nomes e valores que serão associados ao objeto de acordo com as regras do método BindValue. Ao contrário dos métodos EnumerateKeys, EnumerateValues e similares em IModelObject, que podem retornar vários nomes com o mesmo valor (para classes base, modelos pai e similares), esse enumerador retornará apenas o conjunto específico de nomes que serão associados a BindValue e BindReference. Os nomes nunca serão duplicados. Observe que há um custo significativamente maior de enumeração de um objeto por meio do associador de nome do que chamar os métodos IModelObject.
O método EnumerateReferences enumera o conjunto de nomes e referências a eles que serão associados ao objeto de acordo com as regras do método BindReference. Ao contrário dos métodos EnumerateKeys, EnumerateValues e similares em IModelObject, que podem retornar vários nomes com o mesmo valor (para classes base, modelos pai e similares), esse enumerador retornará apenas o conjunto específico de nomes que serão associados a BindValue e BindReference. Os nomes nunca serão duplicados. Observe que há um custo significativamente maior de enumeração de um objeto por meio do associador de nome do que chamar os métodos IModelObject.
Interfaces de depuração de script C++ do modelo de dados do depurador
A infraestrutura para provedores de script no modelo de dados também fornece um conceito sobre a depuração de scripts. Qualquer script que deseje expor os recursos de depuração para o host de depuração e o aplicativo de depurador que hospeda o modelo de dados pode fazer isso fazendo com que scripts depuráveis implementem a interface IDataModelScriptDebug, além da interface IDataModelScript. A presença dessa interface no script indica à infraestrutura que ela é depurável.
Embora a interface IDataModelScriptDebug seja o ponto de partida para obter acesso aos recursos de depuração de um provedor de script, ela é unida por um conjunto de outras interfaces no fornecimento de recursos gerais de depuração.
As interfaces de depuração são:
Interface | Descrição |
---|---|
IDataModelScriptDebug | A interface principal que um provedor de script deve fornecer para tornar um script depurável. A classe de implementação da interface IDataModelScript deve QueryInterface para IDataModelScriptDebug se o script for depurável. |
IDataModelScriptDebugClient | A interface do usuário que deseja fornecer a capacidade de depuração de script implementa a interface IDataModelScriptDebugClient. O provedor de script utiliza essa interface para passar informações de depuração para frente e para trás (por exemplo: eventos que ocorrem, pontos de interrupção etc...) |
IDataModelScriptDebugStack | O provedor de script implementa essa interface para expor a noção de uma pilha de chamadas ao depurador de script. |
IDataModelScriptDebugStackFrame | O provedor de script implementa essa interface para expor a noção de um quadro de pilha específico dentro da pilha de chamadas. |
IDataModelScriptDebugVariableSetEnumerator | O provedor de script implementa essa interface para expor um conjunto de variáveis. Esse conjunto pode representar o conjunto de parâmetros para uma função, o conjunto de variáveis locais ou o conjunto de variáveis dentro de um escopo específico. O significado exato depende de como a interface foi adquirida. |
IDataModelScriptDebugBreakpoint | O provedor de script implementa essa interface para expor a noção e o controle de um ponto de interrupção específico dentro do script. |
IDataModelScriptDebugBreakpointEnumerator | O provedor de script implementa isso para enumerar todos os pontos de interrupção que existem atualmente no script (habilitados ou não). |
As interfaces de gerenciamento gerais são:
Interface | Descrição |
---|---|
IDataModelScriptProvider | A interface principal que um provedor de script deve implementar. Essa é a interface registrada com a parte do gerenciador de scripts do gerenciador de modelos de dados para anunciar o suporte do provedor de um tipo específico de script e registrar-se em uma extensão de arquivo específica |
IDataModelScript | Uma abstração de um script específico que está sendo gerenciado pelo provedor. Cada script carregado ou editado tem uma instância IDataModelScript separada |
IDataModelScriptClient | Uma interface do cliente que é usada pelo provedor de script para comunicar informações a uma interface do usuário. Os provedores de script não implementam essa interface. O aplicativo que hospeda o modelo de dados que deseja fazer uso de provedores de script faz. Um provedor de script chamará métodos do cliente de script para relatar status, erros etc... |
IDataModelScriptHostContext | Uma interface de host que é usada pelo provedor de script como um contêiner para o conteúdo do script. Como o conteúdo de uma superfície de script diferente das manipulações executadas no modelo de objeto do aplicativo depurador cabe ao host de depuração específico. Essa interface permite que o provedor de script obtenha informações sobre onde colocar seu conteúdo. |
IDataModelScriptTemplate | Os provedores de script podem fornecer um ou mais modelos que servem como pontos de partida para os usuários criarem scripts. Um aplicativo de depurador que fornece um editor interno pode pré-filtrar novos scripts com conteúdo de modelo conforme anunciado pelo provedor por meio dessa interface. |
IDataModelScriptTemplateEnumerator | Uma interface de enumerador que o provedor de script implementa para anunciar todos os vários modelos compatíveis. |
IDataModelNameBinder | Um associador de nome – um objeto que pode associar um nome em um contexto a um valor. Para uma determinada expressão, como "foo.bar", um associador de nome é capaz de associar o nome "bar" no contexto do objeto "foo" e produzir um valor ou referência a ele. Os associadores de nomes normalmente não são implementados por um provedor de script; em vez disso, o associador padrão pode ser adquirido do modelo de dados e usado pelo provedor de script. |
Tornando scripts depuráveis: IDataModelScriptDebug
Qualquer script que seja depurável indica essa funcionalidade por meio da presença da interface IDataModelScriptDebug no mesmo componente que implementa IDataModelScript. A consulta para essa interface pelo host de depuração ou pelo aplicativo de depurador que hospeda o modelo de dados é o que indica a presença da funcionalidade de depuração.
A interface IDataModelScriptDebug é definida da seguinte maneira.
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;
}
O método GetDebugState retorna o estado atual do script (por exemplo: se ele está em execução ou não). O estado é definido por um valor dentro da enumeração ScriptDebugState.
O método GetCurrentPosition' retorna a posição atual dentro do script. Isso só pode ser chamado quando o script é dividido no depurador em que uma chamada para GetScriptState retornaria ScriptDebugBreak. Qualquer outra chamada para esse método é inválida e falhará.
O método GetStack obtém a pilha de chamadas atual na posição de interrupção. Esse método só pode ser chamado quando o script é dividido no depurador.
O método SetBreakpoint define um ponto de interrupção dentro do script. Observe que a implementação é livre para ajustar as posições de linha e coluna inseridas para avançar para uma posição de código apropriada. Os números reais de linha e coluna em que o ponto de interrupção foi colocado podem ser recuperados por chamadas de método na interface IDataModelScriptDebugBreakpoint retornada.
Cada ponto de interrupção criado dentro do script por meio do método SetBreakpoint recebe um identificador exclusivo (um inteiro sem sinal de 64 bits) pela implementação. O método FindBreakpointById é usado para obter uma interface para o ponto de interrupção de um determinado identificador.
O método EnumerateBreakpoints retorna um enumerador capaz de enumerar cada ponto de interrupção definido em um script específico.
O método GetEventFilter retorna se "break on event" está habilitado para um evento específico. Os eventos que podem causar "interrupção no evento" são descritos por um membro da enumeração ScriptDebugEventFilter.
O método SetEventFilter altera o comportamento "break on event" para um evento específico, conforme definido por um membro da enumeração ScriptDebugEventFilter. Uma lista completa de eventos disponíveis (e uma descrição dessa enumeração) pode ser encontrada na documentação do método GetEventFilter.
O método StartDebugging "ativa" o depurador para um script específico. O ato de iniciar a depuração não causa ativamente nenhuma interrupção ou etapa de execução. Ele simplesmente torna o script depurável e fornece um conjunto de interfaces para o cliente se comunicar com a interface de depuração.
O método StopDebugging é chamado por um cliente que deseja interromper a depuração. Essa chamada de método pode ser feita a qualquer momento depois que StartDebugging foi feita com êxito (por exemplo: durante uma interrupção, enquanto o script está em execução etc...). A chamada encerra imediatamente todas as atividades de depuração e redefine o estado de volta para antes de StartDebugging ser chamado.
A interface de depuração: IDataModelScriptDebugClient
O aplicativo de depuração de host ou depurador que deseja fornecer uma interface em torno da depuração de script deve fornecer uma implementação da interface IDataModelScriptDebugClient para o depurador de script por meio do método StartDebugging na interface de depuração para o script.
O IDataModelScriptDebugClient é o canal de comunicação no qual os eventos de depuração são passados e o controle vai do mecanismo de execução de script para uma interface do depurador. Ele é definido da seguinte maneira.
DECLARE_INTERFACE_(IDataModelScriptDebugClient, IUnknown)
{
STDMETHOD(NotifyDebugEvent)(_In_ ScriptDebugEventInformation *pEventInfo, _In_ IDataModelScript *pScript, _In_opt_ IModelObject *pEventDataObject, _Inout_ ScriptExecutionKind *resumeEventKind) PURE;
}
Sempre que ocorre qualquer evento que interrompa o depurador de script, o próprio código de depuração faz uma chamada para a interface por meio do método NotifyDebugEvent. Esse método é síncrono. Nenhuma execução do script será retomada até que a interface retorne do evento. A definição do depurador de script destina-se a ser simples: não há absolutamente nenhum evento aninhado que exija processamento. Um evento de depuração é definido por um registro variante conhecido como ScriptDebugEventInformation. Quais campos nas informações de evento são válidos é amplamente definido pelo membro DebugEvent. Ele define o tipo de evento que ocorreu conforme descrito por um membro da enumeração ScriptDebugEvent.
A pilha de chamadas: IDataModelScriptDebugStack
Quando ocorrer um evento que interrompa o depurador de script, a interface de depuração desejará recuperar a pilha de chamadas para o local de interrupção. Isso é feito por meio do método GetStack. Essa pilha é expressa por meio do IDataModelScriptDebugStack, que é definido conforme indicado abaixo.
Observe que a pilha geral pode abranger vários scripts e/ou vários provedores de script. A pilha de chamadas retornada de uma única chamada para o método GetStack na interface de depuração de um script específico deve retornar apenas o segmento da pilha de chamadas dentro dos limites desse script. É inteiramente possível que um mecanismo de depuração de script possa recuperar a pilha de chamadas, pois abrange vários contextos de script se dois scripts do mesmo provedor interagirem. O método GetStack não deve retornar a parte da pilha que está em outro script. Em vez disso, se essa situação puder ser detectada, o quadro de pilha que é o quadro de limite no script deverá marcar-se como um quadro de transição por meio de uma implementação dos métodos IsTransitionPoint e GetTransition nesse quadro de pilha. Espera-se que a interface do depurador una a pilha geral dos vários segmentos de pilha existentes.
É imperativo que as transições sejam implementadas dessa maneira ou a interface de depuração possa direcionar consultas sobre variáveis locais, parâmetros, pontos de interrupção e outros constructos específicos de script para o contexto de script errado! Isso resultará em um comportamento indefinido na interface do depurador.
DECLARE_INTERFACE_(IDataModelScriptDebugStack, IUnknown)
{
STDMETHOD_(ULONG64, GetFrameCount)() PURE;
STDMETHOD(GetStackFrame)(_In_ ULONG64 frameNumber, _COM_Outptr_ IDataModelScriptDebugStackFrame **stackFrame) PURE;
}
O método GetFrameCount retorna o número de quadros de pilha neste segmento da pilha de chamadas. Se o provedor puder detectar quadros em contextos de script diferentes ou de provedores diferentes, ele deverá indicar isso ao chamador pela implementação dos métodos IsTransitionPoint e GetTransition no quadro de entrada nesse segmento de pilha.
O GetStackFrame obtém um quadro de pilha específico do segmento de pilha. A pilha de chamadas tem um sistema de indexação baseado em zero: o quadro de pilha atual em que o evento de interrupção ocorreu é o quadro 0. O chamador do método atual é o quadro 1 (e assim por diante).
Examinando o estado quando quebrado: IDataModelScriptDebugStackFrame
Um quadro específico da pilha de chamadas quando dividido no depurador de script pode ser recuperado por meio de uma chamada para o método GetStackFrame na interface IDataModelScriptDebugStack que representa o segmento de pilha em que a interrupção ocorreu. A interface IDataModelScriptDebugStackFrame que é retornada para representar esse quadro é definida da seguinte maneira.
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;
}
O método GetName retorna o nome de exibição (por exemplo, nome da função) desse quadro. Esse nome será exibido no backtrace de pilha apresentado ao usuário na interface do depurador.
O método GetPosition retorna a posição dentro do script representado pelo quadro de pilha. Esse método só pode ser chamado quando o script está dentro de uma quebra representada pela pilha na qual esse quadro está contido. A posição da linha e da coluna dentro desse quadro sempre é retornada. Se o depurador for capaz de retornar o intervalo da "posição de execução" dentro do script, uma posição final poderá ser retornada no argumento positionSpanEnd. Se o depurador não for capaz disso, os valores de linha e coluna na extremidade de intervalo (se solicitado) deverão ser definidos como zero.
A interface IDataModelScriptDebugStack representa um segmento de uma pilha de chamadas , essa parte da pilha de chamadas que está contida no contexto de um script. Se o depurador for capaz de detectar a transição de um script para outro (ou um provedor de script para outro), ele poderá indicar isso implementando o método IsTransitionPoint e retornando true ou false conforme apropriado. O quadro de pilha de chamadas que inseriu o script em que o segmento se aplica deve ser considerado um ponto de transição. Todos os outros quadros não são.
Se um determinado quadro de pilha for um ponto de transição conforme determinado pelo método IsTransition (consulte a documentação lá para obter uma definição de pontos de transição), o método GetTransition retornará informações sobre a transição. Em particular, esse método retorna o script anterior , aquele que fez uma chamada para o script representado pelo segmento de pilha que contém esse IDataModelScriptDebugStackFrame.
O método Evaluate avalia uma expressão (da linguagem do provedor de script) no contexto do quadro de pilha representado pela interface IDataModelScriptDebugStackFrame na qual esse método foi chamado. O resultado da avaliação da expressão deve ser empacotado do provedor de script como um IModelObject. As propriedades e outros constructos no IModelObject resultante devem ser adquiridos enquanto o depurador está em um estado de interrupção.
O método EnumerateLocals retorna um conjunto de variáveis (representado por uma interface IDataModelScriptDebugVariableSetEnumerator) para todas as variáveis locais que estão no escopo no contexto do quadro de pilha representado pela interface IDataModelScriptDebugStackFrame na qual esse método foi chamado.
O método EnumerateArguments retorna um conjunto de variáveis (representado por uma interface IDataModelScriptDebugVariableSetEnumerator) para todos os argumentos de função da função chamada no quadro de pilha representado pela interface IDataModelScriptDebugStackFrame na qual esse método foi chamado.
Examinando variáveis: IDataModelScriptDebugVariableSetEnumerator
Um conjunto de variáveis no script que está sendo depurado (sejam elas em um escopo específico, os locais de uma função, os argumentos de uma função etc...) é representado por um conjunto de variáveis definido por meio da interface 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;
}
O método Reset redefine a posição do enumerador para onde ele estava imediatamente após a criação , ou seja, antes do primeiro elemento do conjunto.
O método GetNext move o enumerador para a próxima variável no conjunto e retorna o nome, o valor e os metadados da variável associados a ele. Se o enumerador tiver atingido o final do conjunto, o erro E_BOUNDS será retornado. Depois que o marcador de E_BOUNDS tiver sido retornado do método GetNext, ele continuará a produzir E_BOUNDS quando chamado novamente, a menos que uma chamada de Redefinição intervindo seja feita.
Pontos de interrupção: IDataModelScriptDebugBreakpoint
Os pontos de interrupção de script são definidos por meio do método SetBreakpoint na interface de depuração de um determinado script. Esses pontos de interrupção são representados por uma ID exclusiva e uma implementação da interface IDataModelScriptDebugBreakpoint que é definida da seguinte maneira.
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;
}
O método GetId retorna o identificador exclusivo atribuído pelo mecanismo de depuração do provedor de script ao ponto de interrupção. Esse identificador deve ser exclusivo dentro do contexto do script que contém. O identificador de ponto de interrupção pode ser exclusivo para o provedor; no entanto, isso não é necessário.
O método IsEnabled retorna se o ponto de interrupção está habilitado ou não. Um ponto de interrupção desabilitado ainda existe e ainda está na lista de pontos de interrupção para o script, ele está apenas "desativado" temporariamente. Todos os pontos de interrupção devem ser criados no estado habilitado.
O método Enable habilita o ponto de interrupção. Se o ponto de interrupção tiver sido desabilitado, "atingir o ponto de interrupção" depois de chamar esse método causará uma quebra no depurador.
O método Disable desabilita o ponto de interrupção. Após essa chamada, "atingir o ponto de interrupção" depois de chamar esse método não será interrompido no depurador. O ponto de interrupção, embora ainda presente, é considerado "desativado".
O método Remove remove o ponto de interrupção de sua lista de contenção. O ponto de interrupção não existe mais semanticamente após o retorno desse método. A interface IDataModelScriptDebugBreakpoint que representou o ponto de interrupção é considerada órfã após a chamada. Nada mais pode (legalmente) ser feito com ele após essa chamada além de liberá-la.
O método GetPosition retorna a posição do ponto de interrupção dentro do script. O depurador de script deve retornar a linha e a coluna no código-fonte em que o ponto de interrupção está localizado. Se for capaz de fazer isso, ele também poderá retornar um intervalo de origem representado pelo ponto de interrupção preenchendo uma posição final conforme definido pelo argumento positionSpanEnd. Se o depurador não for capaz de produzir esse intervalo e o chamador solicitá-lo, os campos Linha e Coluna da posição final do intervalo deverão ser preenchidos como zero, indicando que os valores não podem ser fornecidos.
Enumeração de ponto de interrupção: IDataModelScriptDebugBreakpointEnumerator
Se um provedor de script der suporte à depuração, ele também deverá acompanhar todos os pontos de interrupção associados a cada script e ser capaz de enumerar esses pontos de interrupção para a interface de depuração. O enumerador para pontos de interrupção é adquirido por meio do método EnumerateBreakpoints na interface de depuração de um determinado script e é definido da seguinte maneira.
DECLARE_INTERFACE_(IDataModelScriptDebugBreakpointEnumerator, IUnknown)
{
STDMETHOD(Reset)() PURE;
STDMETHOD(GetNext)(_COM_Outptr_ IDataModelScriptDebugBreakpoint **breakpoint) PURE;
}
O método Reset redefine a posição do enumerador para onde ele estava logo após a criação do enumerador , ou seja, antes do primeiro ponto de interrupção enumerado.
O método GetNext move o enumerador para o próximo ponto de interrupção a ser enumerado e retorna a interface IDataModelScriptDebugBreakpoint para esse ponto de interrupção. Se o enumerador tiver atingido o final da enumeração, ele retornará E_BOUNDS. Depois que o erro E_BOUNDS tiver sido produzido, as chamadas subsequentes para o método GetNext continuarão a produzir E_BOUNDS, a menos que uma chamada intermediária para o método Reset tenha sido feita.
Confira também
Este tópico faz parte de uma série que descreve as interfaces acessíveis do C++, como usá-las para criar uma extensão de depurador baseada em C++ e como usar outras construções de modelo de dados (por exemplo: JavaScript ou NatVis) de uma extensão de modelo de dados C++.
Visão geral do modelo de dados do depurador C++
Interfaces C++ do modelo de dados do depurador
Objetos C++ do modelo de dados do depurador