Auswerten eines Überwachungsausdrucks
Wichtig
Seit Visual Studio 2015 ist diese Art der Implementierung von Ausdrucksauswertungen veraltet. Informationen zum Implementieren von CLR-Ausdrucksauswertungen finden Sie unter CLR-Ausdrucksauswertungen und Beispiel für die Auswertung verwalteter Ausdrücke.
Wenn Visual Studio bereit ist, den Wert eines Überwachungsausdrucks anzuzeigen, ruft es EvaluateSync auf, was wiederum EvaluateSync aufruft. Dieser Prozess erzeugt ein IDebugProperty2 -Objekt, das den Wert und typ des Ausdrucks enthält.
In dieser Implementierung IDebugParsedExpression::EvaluateSync
wird der Ausdruck analysiert und gleichzeitig ausgewertet. Diese Implementierung führt die folgenden Aufgaben aus:
Analysiert und wertet den Ausdruck aus, um ein generisches Objekt zu erzeugen, das den Wert und seinen Typ enthält. In C# wird dies als
object
eine Weile in C++ dargestellt, dies wird als einVARIANT
.Instanziiert eine Klasse (in diesem Beispiel aufgerufen
CValueProperty
), die dieIDebugProperty2
Schnittstelle implementiert und in der Klasse speichert, die zurückgegeben werden soll.Gibt die
IDebugProperty2
Schnittstelle aus demCValueProperty
-Objekt zurück.
Verwalteter Code
Dies ist eine Implementierung des IDebugParsedExpression::EvaluateSync
verwalteten Codes. Die Hilfsmethode Tokenize
analysiert den Ausdruck in eine Analysestruktur. Die Hilfsfunktion EvalToken
konvertiert das Token in einen Wert. Die Hilfsfunktion FindTerm
durchläuft rekursiv die Analysestruktur und ruft EvalToken
für jeden Knoten, der einen Wert darstellt, und wendet alle Vorgänge (Addition oder Subtraktion) im Ausdruck an.
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;
}
}
}
Nicht verwalteter Code
Dies ist eine Implementierung des IDebugParsedExpression::EvaluateSync
nicht verwalteten Codes. Die Hilfsfunktion Evaluate
analysiert und wertet den Ausdruck aus und gibt einen VARIANT
Haltewert für den resultierenden Wert zurück. Die Hilfsfunktion VariantValueToProperty
bündelt das VARIANT
Objekt in ein CValueProperty
Objekt.
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;
}