Évaluer une expression espionne
Important
Dans Visual Studio 2015, cette façon d’implémenter des évaluateurs d’expression est déconseillée. Pour plus d’informations sur l’implémentation d’évaluateurs d’expression CLR, consultez l’exemple d’évaluateur d’expression CLR et d’évaluateur d’expression managée.
Lorsque Visual Studio est prêt à afficher la valeur d’une expression espionne, elle appelle EvaluateSync, qui appelle à son tour EvaluateSync. Ce processus produit un objet IDebugProperty2 qui contient la valeur et le type de l’expression.
Dans cette implémentation de IDebugParsedExpression::EvaluateSync
, l’expression est analysée et évaluée en même temps. Cette implémentation effectue les tâches suivantes :
Analyse et évalue l’expression pour produire un objet générique qui contient la valeur et son type. En C#, il s’agit d’un
object
moment en C++, il est représenté sous la forme d’unVARIANT
.Instancie une classe (appelée
CValueProperty
dans cet exemple) qui implémente l’interfaceIDebugProperty2
et stocke dans la classe la valeur à retourner.Retourne l’interface
IDebugProperty2
de l’objetCValueProperty
.
Code managé
Il s’agit d’une implémentation du IDebugParsedExpression::EvaluateSync
code managé. La méthode Tokenize
d’assistance analyse l’expression dans une arborescence d’analyse. La fonction EvalToken
d’assistance convertit le jeton en valeur. La fonction FindTerm
d’assistance traverse de manière récursive l’arborescence d’analyse, en appelant EvalToken
chaque nœud représentant une valeur et en appliquant toutes les opérations (addition ou soustraction) dans l’expression.
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;
}
}
}
Code non managé
Il s’agit d’une implémentation du IDebugParsedExpression::EvaluateSync
code non managé. La fonction Evaluate
d’assistance analyse et évalue l’expression, retournant une VARIANT
conservation de la valeur résultante. La fonction VariantValueToProperty
d’assistance regroupe l’objet VARIANT
dans un CValueProperty
objet.
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;
}