조사식 식의 계산
Visual Studio 조사식의 값을 표시할 준비가 되 면 호출 IDebugExpression2::EvaluateSync 를 차례로 호출 IDebugParsedExpression::EvaluateSync. 이렇게 생성 된 IDebugProperty2 값과 식의 형식을 포함 하는 개체입니다.
이 구현에서는 IDebugParsedExpression::EvaluateSync, 식을 구문 분석 하 고 동시에 평가 합니다. 이 구현에서는 다음 작업을 수행합니다.
분석 한 값 및 해당 형식을 포함 하는 일반 개체를 생성 하는 식을 계산 합니다. C#에서 이것은 표시 됩니다는 object c + +에서는이 이름으로 표시 된 VARIANT.
클래스를 인스턴스화합니다 (라는 CValueProperty 이 예제에서는) 구현 하는 IDebugProperty2 인터페이스 및 클래스에서 반환 하는 값을 저장 합니다.
반환은 IDebugProperty2 에서 인터페이스는 CValueProperty 개체입니다.
관리 코드
이 구현 하는 것은 IDebugParsedExpression::EvaluateSync 관리 되는 코드입니다. 도우미 메서드 Tokenize 식에 구문 분석 트리를 구문 분석 합니다. 도우미 EvalToken 토큰을 값으로 변환 합니다. 도우미 FindTerm 구문 분석 트리를 재귀적으로 순회를 호출 EvalToken 값을 표시 하 고 식에 적용 하는 작업 (더하기 나 빼기) 각 노드에 대 한.
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;
}
}
}
관리 되지 않는 코드
이렇게 구현 하는 것은 IDebugParsedExpression::EvaluateSync 관리 되지 않는 코드에서. 도우미 함수 Evaluate 구문 분석 하 고 반환 하는 식을 계산 된 VARIANT 결과 값을 보유 합니다. 도우미 함수 VariantValueToProperty 번들의 VARIANT 에 있는 CValueProperty 개체입니다.
[C++]
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;
}