【问题标题】:Obtaining property values of a class using GetFieldProps使用 GetFieldProps 获取类的属性值
【发布时间】:2018-02-12 09:33:55
【问题描述】:

我正在尝试使用 GetFieldProps 获取类中字段的值

最初我使用GetClassLayout 来获取FieldDef 令牌数组,然后使用GetFieldProps 枚举它们。

每个GetFieldProps 调用的结果返回S_OK 并且确实填充szField 中的字段名称。

我在 ExceptionThrown 回调中调用尝试此操作,当尝试此异常时,它返回 _className_message 等字段名称,但 ppValue 始终为空,@987654331 也是如此@。

如何获取类中字段的值?

这是我当前方法的一个示例(删除了声明等):

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

【问题讨论】:

  • GetFieldProps 仅提供静态信息,因此 pValuepcchValue 可能仅与表示常量的字段相关。要从实例中获取实际值,我相信您需要使用 GetClassLayout 返回的COR_FIELD_OFFSET.ulOffset,相对于 ObjectID(ObjectID 是指向实际实例的指针)。
  • @BrianReichle 谢谢。你知道是否有任何关于如何做到这一点的文档,或者你有一些指示吗?有很多关于单个方法的文档,例如GetClassLayout,但我找不到太多关于将它们连接在一起的信息。例如,即使我知道字段值相对于 classId 的位置,当我不知道它的大小等时如何读取它的值?

标签: c++ .net clr coreclr imetadataimport


【解决方案1】:

GetFieldProps 只提供静态信息,所以pValue & pcchValue 可能只与表示常量的字段相关。

要从实例中获取实际值,我相信您需要使用GetClassLayout返回的COR_FIELD_OFFSET.ulOffset来获取相对于ObjectID的内存位置(ObjectID是指向实际实例的指针),您可以得到通过解析GetFieldProps 存储在ppvSigBlobpcbSigBlob 中的签名获得所需的大小/解释(其格式在ECMA-335 Partition II 第23.2.4 节中定义)。

  • 如果类型是原始值类型,那么大小和解释应该是不言而喻的(例如,Int32 将是一个 4 字节整数)。
  • 如果类型是引用类型,那么它将是包含 ObjectID 的原生 int 大小的字段。
  • 如果类型是枚举,那么它将具有其基础类型的大小(ECMA-335 Partition II 第 14.3 节)。
  • 如果类型是非原始类型,则可以使用GetClassLayout 查找其组件字段的位置。
  • 您可以分别使用GetStringLayoutGetArrayObjectInfo 进一步分解字符串和数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多