Aracılığıyla paylaş


İzleme ifadesini değerlendirin

Önemli

Visual Studio 2015'te, ifade değerlendiricileri uygulama yöntemi kullanım dışıdır. CLR ifade değerlendiricilerini uygulama hakkında bilgi için bkz. CLR ifade değerlendiricileri ve Yönetilen ifade değerlendirici örneği.

Visual Studio bir izleme ifadesinin değerini görüntülemeye hazır olduğunda EvaluateSync'i çağırır ve bu da EvaluateSync'i çağırır. Bu işlem, ifadenin değerini ve türünü içeren bir IDebugProperty2 nesnesi oluşturur.

Bu IDebugParsedExpression::EvaluateSync uygulamasında, ifade ayrıştırılır ve aynı anda değerlendirilir. Bu uygulama aşağıdaki görevleri gerçekleştirir:

  1. Değeri ve türünü tutan genel bir nesne oluşturmak için ifadeyi ayrıştırıp değerlendirir. C# dilinde, bu object olarak temsil edilirken, C++ dilinde, bu VARIANT olarak temsil edilir.

  2. Bir sınıfın (bu örnekte adı CValueProperty olan) örneğini oluşturur, bu sınıf IDebugProperty2 arabirimini uygular ve döndürülecek değeri kendi içinde depolar.

  3. CValueProperty nesnesinden IDebugProperty2 arabirimi döndürür.

Yönetilen kod

Bu, yönetilen kodun IDebugParsedExpression::EvaluateSync bir uygulamasıdır. yardımcı yöntem Tokenize, ifadeyi bir ayrıştırma ağacına ayrıştırıyor. Yardımcı işlevi EvalToken belirteci bir değere dönüştürür. Yardımcı işlevi FindTerm ayrıştırma ağacında yinelemeli olarak geçiş yaparak bir değeri temsil eden her düğümü çağırır EvalToken ve ifadedeki tüm işlemleri (toplama veya çıkarma) uygular.

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

Yönetilmeyen kod

Bu, yönetilmeyen kodun IDebugParsedExpression::EvaluateSync bir uygulamasıdır. Yardımcı işlev Evaluate ifadesini ayrıştırır ve değerlendirir, elde edilen değeri barındıran bir VARIANT döndürür. yardımcı işlev VariantValueToProperty ve VARIANT ögelerini bir CValueProperty nesnesi içine paketler.

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