Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Ważne
W programie Visual Studio 2015 ten sposób implementowania ewaluatorów wyrażeń jest przestarzały. Aby uzyskać informacje na temat implementowania ewaluatorów wyrażeń CLR, zobacz ewaluatory wyrażeń CLR oraz przykład ewaluatora wyrażeń zarządzanych.
Gdy program Visual Studio jest gotowy do wyświetlenia wartości wyrażenia zegarka, wywołuje metodę EvaluateSync, która z kolei wywołuje metodę EvaluateSync. Ten proces tworzy obiekt IDebugProperty2 zawierający wartość i typ wyrażenia.
W tej implementacji IDebugParsedExpression::EvaluateSync wyrażenie jest analizowane i oceniane jednocześnie. Ta implementacja wykonuje następujące zadania:
Analizuje i ocenia wyrażenie w celu utworzenia obiektu ogólnego, który zawiera wartość i jego typ. W języku C# jest to reprezentowane jako
object, a w C++ jakoVARIANT.Tworzy wystąpienie klasy (nazywanej
CValuePropertyw tym przykładzie), która implementuje interfejsIDebugProperty2i przechowuje wartość, która ma zostać zwrócona.IDebugProperty2Zwraca interfejs zCValuePropertyobiektu .
Kod zarządzany
Jest to implementacja kodu zarządzanego IDebugParsedExpression::EvaluateSync . Metoda Tokenize pomocnika analizuje wyrażenie w drzewie analizy. Funkcja EvalToken pomocnika konwertuje token na wartość. Funkcja FindTerm pomocnika rekursywnie przechodzi przez drzewo analizy, wywołując EvalToken dla każdego węzła reprezentującego wartość i stosując dowolne operacje (dodawanie lub odejmowanie) w wyrażeniu.
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;
}
}
}
Niezarządzany kod
Jest to implementacja IDebugParsedExpression::EvaluateSync w kodzie niezarządzanym. Funkcja pomocnicza Evaluate analizuje i oblicza wyrażenie, zwracając VARIANT zawierający wartość wynikową. Funkcja pomocnicza VariantValueToProperty grupuje VARIANT w obiekt CValueProperty.
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;
}