1

I am trying to obtain the values of the fields in a class using GetFieldProps

Initially I use GetClassLayout to get an array of FieldDef tokens, then enumerate them using GetFieldProps.

The result of each GetFieldProps call returns S_OK and does populate the name of the field in szField.

I am calling trying this in an ExceptionThrown callback, and when attempting this for the exception, it returns field names of _className, _message etc., but ppValue is always empty, as is pcchValue.

How do I get the value of fields in a class?

This is a sample of my current approach (with declarations etc. removed):

COR_FIELD_OFFSET* fieldTokensAndOffsets = new COR_FIELD_OFFSET[fieldArraySize];
m_info->GetClassLayout(
    classId,
    fieldTokensAndOffsets,
    fieldArraySize,
    &a,  
    &b);


for (int i = 0; i < fieldArraySize - 1; i++) {

    auto rid = fieldTokensAndOffsets[i].ridOfField;

    MetaDataImport->GetFieldProps(
        rid,
        &mb,
        fieldName,
        100,,
        &pchField,
        &pdwAttr,
        &ppvSigBlob,
        &pcbSigBlob,
        &pdwCPlusTypeFlag,
        &pValue,
        &pcchValue
    );
}
Dave S
  • 1,403
  • 1
  • 15
  • 23
  • 1
    GetFieldProps only provides static information, so `pValue` & `pcchValue` are probably only relevant for fields representing constants. To get the actual value from an instance, I believe you need to use the `COR_FIELD_OFFSET.ulOffset` returned by GetClassLayout, relative to the ObjectID (ObjectID is a pointer to the actual instance). – Brian Reichle Feb 12 '18 at 10:07
  • @BrianReichle Thank you. Do you know if there is any documentation on how to do that, or do you have some pointers please? There is lots of documentation about individual methods such as `GetClassLayout`, but I can't find much on connecting them together. For example, even when I know the location of the field's value relative to the classId, how do I go about reading its value when I don't know its size etc.? – Dave S Feb 12 '18 at 14:09

1 Answers1

1

GetFieldProps only provides static information, so pValue & pcchValue are probably only relevant for fields representing constants.

To get the actual value from an instance, I believe you need to use the COR_FIELD_OFFSET.ulOffset returned by GetClassLayout to get the memory location relative to the ObjectID (ObjectID is a pointer to the actual instance) and you can get the required size/interpretation by parsing the signature that GetFieldProps stores in ppvSigBlob and pcbSigBlob (the format of which is defined in ECMA-335 Partition II Section 23.2.4).

  • If the type is a primitive value type, then the size and interpretation should be self evident (eg. Int32 will be a 4 byte integer).
  • If the type is a reference type, then it will be a native int sized field containing the ObjectID.
  • If the type is an enum, then it will have the size of it's underlying type (ECMA-335 Partition II Section 14.3).
  • If the type is a non-primitive type, then you can use GetClassLayout to find the location of it's component fields.
  • you can get a further break-down of strings and arrays using GetStringLayout and GetArrayObjectInfo respectfully.
Brian Reichle
  • 2,798
  • 2
  • 30
  • 34