Freigeben über


Auswerten eines Überwachungs-Ausdruck

Wenn Visual Studio bereit ist, den Wert eines Ausdrucks für Überwachung anzuzeigen, ruft es IDebugExpression2::EvaluateSync an, das wiederum IDebugParsedExpression::EvaluateSyncaufruft. Dadurch wird ein IDebugProperty2-Objekt, das den Wert als auch den Typ des Ausdrucks enthält.

In dieser Implementierung von IDebugParsedExpression::EvaluateSync, wird der Ausdruck analysiert und gleichzeitig ausgewertet. Diese Implementierung führt die folgenden Aufgaben aus:

  1. Analysiert und wertet den Ausdruck aus, um ein generisches Objekt zu erstellen, das den Wert und den Typ enthält. In C# wird dies als object dargestellt, während in C++ dies als VARIANTdargestellt wird.

  2. Instanziiert eine Klasse in diesem Beispiel CValueProperty () implementiert die IDebugProperty2 und speichert Schnittstelle in der Klasse den zurückzugebenden Wert.

  3. Gibt die IDebugProperty2-Schnittstelle aus dem CValueProperty-Objekt zurück.

Verwalteter Code

Dies ist eine Implementierung IDebugParsedExpression::EvaluateSync in verwaltetem Code. Die Hilfsmethode Tokenize analysiert den Ausdruck in eine Analysestruktur. Die Hilfsfunktion EvalToken konvertiert das Token mit einem Wert. Die Hilfsfunktion FindTerm durchläuft rekursiv die Analysestruktur und ruft EvalToken für jeden Knoten an, die einen Wert darstellt und wendet alle Vorgänge (Addition oder Subtraktion) im Ausdruck.

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 IDebugParsedExpression::EvaluateSync in nicht verwaltetem Code. Die Hilfsfunktion Evaluate analysiert und wertet den Ausdruck aus und gibt VARIANT zurück, das den resultierenden Wert enthält. Die Hilfsfunktion VariantValueToProperty bündelt VARIANT in ein CValueProperty-Objekt.

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

Siehe auch

Konzepte

Auswerten eines Überwachungsfenster-Ausdruck

Ausdrucksauswertung zur Implementierung des Beispiels