Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
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 de surveillance, il 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#, ceci est représenté par un
object, tandis qu'en C++, ceci est représenté par unVARIANT.Instancie une classe (appelée
CValuePropertydans cet exemple) qui implémente l’interfaceIDebugProperty2et stocke dans la classe la valeur à retourner.Retourne l’interface
IDebugProperty2de l’objetCValueProperty.
Code managé
Il s’agit d’une implémentation du IDebugParsedExpression::EvaluateSync en code géré. La méthode utilitaire Tokenize analyse l’expression pour obtenir 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 dans le code non géré. La fonction d’assistance Evaluate analyse et évalue l’expression, retournant un VARIANT contenant 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;
}