Avaliar uma expressão de observação
Importante
No Visual Studio 2015, essa maneira de implementar avaliadores de expressão foi preterida. Para obter informações sobre como implementar avaliadores de expressão CLR, consulte Avaliadores de expressão CLR e Exemplo de avaliador de expressão gerenciada.
Quando o Visual Studio está pronto para exibir o valor de uma expressão de observação, ele chama EvaluateSync, que por sua vez chama EvaluateSync. Esse processo produz um objeto IDebugProperty2 que contém o valor e o tipo da expressão.
Nesta implementação do IDebugParsedExpression::EvaluateSync
, a expressão é analisada e avaliada ao mesmo tempo. Essa implementação executa as seguintes tarefas:
Analisa e avalia a expressão para produzir um objeto genérico que contém o valor e seu tipo. Em C#, isso é representado como um tempo em C++, isso é representado como um
object
VARIANT
arquivo .Instancia uma classe (chamada
CValueProperty
neste exemplo) que implementa a interface e armazena na classe o valor aIDebugProperty2
ser retornado.Retorna a
IDebugProperty2
interface doCValueProperty
objeto.
Código gerenciado
Esta é uma implementação do IDebugParsedExpression::EvaluateSync
código gerenciado in. O método Tokenize
auxiliar analisa a expressão em uma árvore de análise. A função EvalToken
auxiliar converte o token em um valor. A função FindTerm
auxiliar percorre recursivamente a árvore de análise, chamando EvalToken
cada nó que representa um valor e aplicando quaisquer operações (adição ou subtração) na expressão.
namespace EEMC
{
public class CParsedExpression : IDebugParsedExpression
{
public HRESULT EvaluateSync(
uint evalFlags,
uint timeout,
IDebugSymbolProvider provider,
IDebugAddress address,
IDebugBinder binder,
string resultType,
out IDebugProperty2 result)
{
HRESULT retval = COM.S_OK;
this.evalFlags = evalFlags;
this.timeout = timeout;
this.provider = provider;
this.address = address;
this.binder = binder;
this.resultType = resultType;
try
{
IDebugField field = null;
// Tokenize, then parse.
tokens = Tokenize(expression);
result = new CValueProperty(
expression,
(int) FindTerm(EvalToken(tokens[0], out field),1),
field,
binder);
}
catch (ParseException)
{
result = new CValueProperty(expression, "Huh?");
retval = COM.E_INVALIDARG;
}
return retval;
}
}
}
Código não gerenciado
Esta é uma implementação do IDebugParsedExpression::EvaluateSync
código não gerenciado in. A função Evaluate
auxiliar analisa e avalia a expressão, retornando uma VARIANT
retenção do valor resultante. A função VariantValueToProperty
auxiliar agrupa o VARIANT
em um CValueProperty
objeto.
STDMETHODIMP CParsedExpression::EvaluateSync(
in DWORD evalFlags,
in DWORD dwTimeout,
in IDebugSymbolProvider* pprovider,
in IDebugAddress* paddress,
in IDebugBinder* pbinder,
in BSTR bstrResultType,
out IDebugProperty2** ppproperty )
{
// dwTimeout parameter is ignored in this implementation.
if (pprovider == NULL)
return E_INVALIDARG;
if (paddress == NULL)
return E_INVALIDARG;
if (pbinder == NULL)
return E_INVALIDARG;
if (ppproperty == NULL)
return E_INVALIDARG;
else
*ppproperty = 0;
HRESULT hr;
VARIANT value;
BSTR bstrErrorMessage = NULL;
hr = ::Evaluate( pprovider,
paddress,
pbinder,
m_expr,
&bstrErrorMessage,
&value );
if (hr != S_OK)
{
if (bstrErrorMessage == NULL)
return hr;
//we can display better messages ourselves.
HRESULT hrLocal = S_OK;
VARIANT varType;
VARIANT varErrorMessage;
VariantInit( &varType );
VariantInit( &varErrorMessage );
varErrorMessage.vt = VT_BSTR;
varErrorMessage.bstrVal = bstrErrorMessage;
CValueProperty* valueProperty = new CValueProperty();
if (valueProperty != NULL)
{
hrLocal = valueProperty->Init(m_expr, varType, varErrorMessage);
if (SUCCEEDED(hrLocal))
{
hrLocal = valueProperty->QueryInterface( IID_IDebugProperty2,
reinterpret_cast<void**>(ppproperty) );
}
}
VariantClear(&varType);
VariantClear(&varErrorMessage); //frees BSTR
if (!valueProperty)
return hr;
valueProperty->Release();
if (FAILED(hrLocal))
return hr;
}
else
{
if (bstrErrorMessage != NULL)
SysFreeString(bstrErrorMessage);
hr = VariantValueToProperty( pprovider,
paddress,
pbinder,
m_radix,
m_expr,
value,
ppproperty );
VariantClear(&value);
if (FAILED(hr))
return hr;
}
return S_OK;
}