Vyhodnocení místních hodnot
Důležité
V sadě Visual Studio 2015 je tento způsob implementace vyhodnocovačů výrazů zastaralý. Informace o implementaci vyhodnocovačů výrazů CLR najdete v tématu vyhodnocovače výrazů CLR a ukázka vyhodnocovače spravovaných výrazů.
GetPropertyInfo je volána k získání hodnoty místního, stejně jako název a typ místního. Vzhledem k tomu, že hodnota místního prostředí závisí na aktuálním stavu programu, musí být hodnota místního prostředí získána z paměti. IDebugBinder objekt je použit k vytvoření vazby IDebugField objekt představující místní k příslušnému umístění v paměti obsahující hodnotu. Toto umístění v paměti je reprezentováno objektem IDebugObject .
Tato funkce načítání hodnoty místního prostředí je zapouzdřena do pomocné funkce, která provádí následující úlohy:
Vytvoří vazbu objektu
IDebugField
na paměť k získání objektuIDebugObject
.Získá hodnotu z paměti. Tato hodnota je reprezentována jako řada bajtů.
Naformátuje hodnotu na základě typu místního.
Vrátí obecný objekt, který obsahuje hodnotu místního objektu. V jazyce C# je to a
object
v jazyce C++ se jedná o .VARIANT
Spravovaný kód
Toto je implementace funkce, která načte hodnotu místního ve spravovaném kódu.
namespace EEMC
{
internal class Field
{
internal static object GetValue(
IDebugBinder binder,
IDebugField field,
Type t,
uint size)
{
if (t == null || size == 0) return null;
IDebugObject debugObject = null;
binder.Bind(null, field, out debugObject);
byte[] buffer = new byte[size];
for (int i = 0; i < size; i++) buffer[i] = 0;
debugObject.GetValue(buffer, size);
if (t == typeof(sbyte)) return (sbyte) buffer[0];
if (t == typeof(short)) return BitConverter.ToInt16(buffer, 0);
if (t == typeof(int)) return BitConverter.ToInt32(buffer, 0);
if (t == typeof(long)) return BitConverter.ToInt64(buffer, 0);
if (t == typeof(byte)) return buffer[0];
if (t == typeof(char)) return BitConverter.ToChar(buffer, 0);
if (t == typeof(uint)) return BitConverter.ToUInt32(buffer, 0);
if (t == typeof(ulong)) return BitConverter.ToUInt64(buffer, 0);
if (t == typeof(float)) return BitConverter.ToSingle(buffer, 0);
if (t == typeof(double)) return BitConverter.ToDouble(buffer, 0);
if (t == typeof(bool)) return BitConverter.ToBoolean(buffer, 0);
if (t == typeof(string)) return BitConverter.ToString(buffer, 0);
return null;
}
}
}
Nespravovaný kód
Toto je implementace funkce, která načte hodnotu místního v nespravovaném kódu. FieldGetType
je zobrazena v oblasti Získání místních hodnot.
HRESULT FieldGetPrimitiveValue(
in IDebugBinder* pbinder,
in IDebugField* pfield,
out VARIANT* pvarValue
)
{
if (pvarValue == NULL)
return E_INVALIDARG;
else
*pvarValue = 0;
if (pfield == NULL)
return E_INVALIDARG;
if (pbinder == NULL)
return E_INVALIDARG;
HRESULT hr;
UINT valueSize = 0;
BYTE* pvalueBits = NULL;
IDebugObject* pobject = NULL;
//get the value as bits
hr = pbinder->Bind( NULL, pfield, &pobject );
if (FAILED(hr))
return hr;
hr = pobject->GetSize( &valueSize );
if (FAILED(hr))
{
pobject->Release();
return hr;
}
pvalueBits = reinterpret_cast<BYTE *>(malloc(valueSize * sizeof(BYTE)));
if (!pvalueBits)
{
pobject->Release();
return E_OUTOFMEMORY;
}
hr = pobject->GetValue( pvalueBits, valueSize );
pobject->Release();
if (FAILED(hr))
{
free(pvalueBits);
return hr;
}
//get the type
VARIANT valueType;
hr = FieldGetType( pfield, &valueType );
if (FAILED(hr))
{
free(pvalueBits);
return hr;
}
//copy a primitive value
switch (valueType.vt)
{
case VT_BSTR:
{
pvarValue->vt = VT_BSTR;
if (valueSize == 0)
pvarValue->bstrVal = SysAllocString( OLE("") );
else
pvarValue->bstrVal =
SysAllocStringByteLen( reinterpret_cast<char*>(pvalueBits),
valueSize );
}
case VT_BOOL:
case VT_I1:
case VT_I2:
case VT_I4:
case VT_I8:
case VT_UI1:
case VT_UI2:
case VT_UI4:
case VT_UI8:
case VT_R4:
case VT_R8:
pvarValue->vt = valueType.vt;
if (valueSize > 8)
valueSize = 8;
memcpy( &(pvarValue->iVal), pvalueBits, valueSize );
break;
case VT_VOID:
case VT_EMPTY:
pvarValue->vt = valueType.vt;
break;
default:
//not a primitive type
VariantClear(&valueType);
free(pvalueBits);
return E_FAIL;
}
free(pvalueBits);
VariantClear(&valueType);
return S_OK;
}