지역 변수를 계산
IDebugProperty2::GetPropertyInfo지역 뿐만 아니라 지역 변수의 이름 및 유형 값을 얻기 위해 호출 됩니다. 값을 로컬 프로그램의 현재 상태에 따라 달라 집니다 이후 지역 변수의 값 메모리에서 얻어야 합니다. IDebugBinder 개체가 바인딩하는 데 사용 되는 IDebugField 의 로컬 값을 포함 하는 메모리에서 해당 위치를 나타내는 개체입니다. 이 메모리 위치에에서 표시 되는 IDebugObject 개체입니다.
로컬의 값을 검색 하는이 기능은 다음 작업을 수행 하는 도우미 함수에 캡슐화 됩니다.
바인딩하는 IDebugField 개체에 메모리를 얻을 수는 IDebugObject 개체입니다.
메모리에서 값을 가져옵니다. 이 값은 일련의 바이트 수로 표현 됩니다.
지역 변수의 형식에 따라 값 서식을 지정 합니다.
지역 변수의 값을 포함 하는 일반 개체를 반환 합니다. C#이 되는 object, 및 c + +에서이 VARIANT.
관리 코드
이 구현 하는 관리 되는 코드에는 로컬 값을 검색 하는 함수입니다.
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;
}
}
}
관리 되지 않는 코드
이 구현 하는 관리 되지 않는 코드에서 로컬 값을 검색 하는 함수입니다. FieldGetType나와 로컬 값 가져오기.
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;
}