Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Importante
En Visual Studio 2015, esta forma de implementar evaluadores de expresiones está en desuso. Para obtener información sobre la implementación de evaluadores de expresiones CLR, consulte 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, mientras que en C++, se representa como unVARIANT.Crea una instancia de una clase (denominada
CValuePropertyen este ejemplo) que implementa laIDebugProperty2interfaz y almacena en la clase el valor que se va a devolver.Devuelve la
IDebugProperty2interfaz delCValuePropertyobjeto .
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 auxiliar Evaluate parsea y evalúa la expresión, devolviendo un VARIANT que 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;
}