Evaluación de una expresión de inspección
Importante
En Visual Studio 2015, esta forma de implementar evaluadores de expresiones está en desuso. Para obtener información sobre cómo implementar evaluadores de expresiones CLR, vea Evaluadores de expresiones CLR y Ejemplo de evaluador de expresiones administradas.
Cuando Visual Studio está listo para mostrar el valor de una expresión de inspección, llama a EvaluateSync, que a su vez llama a EvaluateSync. Este proceso genera un objeto IDebugProperty2 que contiene el valor y el tipo de la expresión.
En esta implementación de IDebugParsedExpression::EvaluateSync
, la expresión se analiza y evalúa al mismo tiempo. Esta implementación realiza las siguientes tareas:
Analiza y evalúa la expresión para generar un objeto genérico que contiene el valor y su tipo. En C#, esto se representa como un
object
elemento while en C++, se representa como .VARIANT
Crea una instancia de una clase (denominada
CValueProperty
en este ejemplo) que implementa laIDebugProperty2
interfaz y almacena en la clase el valor que se va a devolver.Devuelve la interfaz
IDebugProperty2
desde el objetoCValueProperty
.
Código administrado
Se trata de una implementación de IDebugParsedExpression::EvaluateSync
en código administrado. El método Tokenize
auxiliar analiza la expresión en un árbol de análisis. La función EvalToken
auxiliar convierte el token en un valor. La función FindTerm
auxiliar recorre recursivamente el árbol de análisis, llamando EvalToken
a para cada nodo que representa un valor y aplicando cualquier operación (suma o resta) en la expresión.
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 no administrado
Se trata de una implementación de IDebugParsedExpression::EvaluateSync
en código no administrado. La función Evaluate
auxiliar analiza y evalúa la expresión, devolviendo un que VARIANT
contiene el valor resultante. La función VariantValueToProperty
auxiliar agrupa el objeto VARIANT
en un 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;
}