Condividi tramite


Valutazione di un'espressione espressioni di controllo

Quando Visual Studio è pronto per visualizzare il valore di un'espressione di controllo, chiama IDebugExpression2:: EvaluateSync a sua volta chiama IDebugParsedExpression:: EvaluateSync. Questa operazione produce IDebugProperty2 un oggetto contenente il valore e il tipo dell'espressione.

In questa implementazione di IDebugParsedExpression::EvaluateSync, l'espressione viene analizzata e valutati contemporaneamente. Questa implementazione esegue le attività seguenti:

  1. Analizza e valuta l'espressione per produrre un oggetto generico che utilizza il valore e il tipo. In c#, questo viene rappresentato come object mentre in C++ è rappresentato come VARIANT.

  2. Creare un'istanza di una classe (chiamata CValueProperty in questo esempio) che implementa l'interfaccia e gli archivi di IDebugProperty2 nella classe il valore da restituire.

  3. Restituisce l'interfaccia di IDebugProperty2 dall'oggetto di CValueProperty .

Codice gestito

Si tratta di un'implementazione di IDebugParsedExpression::EvaluateSync nel codice gestito. Il metodo di supporto Tokenize analizza l'espressione in una struttura ad albero di analisi. La funzione di supporto EvalToken converte il token a un valore. La funzione di supporto FindTerm in modo ricorsivo attraversa la struttura ad albero di traccia, chiamando EvalToken per ogni nodo che rappresenta un valore e che applica tutte le operazioni (aggiunta o meno) nell'espressione.

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;
        }
    }
}

codice non gestito

Si tratta di un'implementazione di IDebugParsedExpression::EvaluateSync nel codice non gestito. La funzione di supporto Evaluate analizza e valuta l'espressione, restituendo VARIANT che utilizza il valore risultante. la funzione di supporto VariantValueToProperty aggrega VARIANT in un oggetto di 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;
}

Vedere anche

Concetti

Valutare l'espressione la finestra Espressioni di controllo

Implementazione dell'esempio di valutazione di espressioni