【问题标题】:How can I access structure fields by name at run time?如何在运行时按名称访问结构字段?
【发布时间】:2010-03-25 13:08:23
【问题描述】:

C 常见问题以某种方式解释它,here is the link.

但我看不懂,谁能给我解释一下?还是给我另一种方式?

非常感谢!

【问题讨论】:

  • A 没问题,但 Q sux。谷歌“java反射”,C语言没有任何支持。
  • 我知道反射,C 通过跳转图支持它,java 反射,不是我的问题,但仍然感谢。

标签: c struct


【解决方案1】:

我认为这个例子让答案很清楚:

struct test
{
    int b;
    int a;
};

int main() 
{
    test t;
    test* structp = &t;

    //Find the byte offset of 'a' within the structure
    int offsetf = offsetof(test, a);

    //Set the value of 'a' using pointer arithmetic
    *(int *)((char *)structp + offsetf) = 5;

    return 0;

}

【讨论】:

  • 我认为值得指出的是,这里的“名称”(a)是一个编译时符号,而不是“在运行时”找到的东西。在后一种情况下,它必须是一个字符串,并且 offsetof() 不起作用。
【解决方案2】:

你不能,除非你自己实现某种名称查找。

C在程序运行时没有留下任何时间名称信息。

对于不同的结构体字段类型通常支持这一点很复杂。

【讨论】:

    【解决方案3】:

    如果您使用调试信息编译了二进制文件,则可以使用它在运行时查找名称。例如gcc(通常)以DWARF 格式生成调试信息,您可以使用libdwarf 对其进行处理。

    如果是 DWARF,您可以在 DW_TAG_member 节点中找到您的字段,DW_AT_data_member_location 属性将为您提供字段的偏移量,与您在编译时从 offsetof() 获得的相同。

    【讨论】:

      【解决方案4】:

      如果使用struct {...} 定义定义结构,则在可执行代码中不太可能存在与成员名称相关的任何信息。一些平台将“调试”信息构建到生成的可执行文件中,运行中的程序可能会通过某种方式检索该信息,但没有通用的方法来执行此类操作。

      然而,我们可以做的是使用宏来定义一个结构。例如,可以定义:

      #define MAKE_ACME_STRUCT \
        FIELD(id,int,23) \
        X FIELD(name,char30,"Untitled") \
        X FIELD(info,int,19) \
        // LEAVE THIS COMMENT HERE
      

      然后多次调用 MAKE_ACME_STRUCT 宏,FIELD 和 X 宏定义不同的方式,以便它可以扩展为结构语句,或该结构的“默认”实例的初始化表达式,或作为描述结构字段的项目数组的初始化表达式[例如像

      STRUCT_INFO acme_struct_info[] = {
        {"id", STRUCT_INFO_TYPE_int, sizeof(ACME_STRUCT.id), offsetof(ACME_STRUCT.id)}
        ,{"name", STRUCT_INFO_TYPE_char30, sizeof(ACME_STRUCT.name), offsetof(ACME_STRUCT.name)}
        ,{"info", STRUCT_INFO_TYPE_int, sizeof(ACME_STRUCT.info), offsetof(ACME_STRUCT.info)}
        ,{0}};
      

      结构中使用的所有类型都必须具有单标记名称,并且对于每个这样的名称,定义一个标识符STRUCT_INFO_TYPE_nameGoesHere,它以它可以理解的某种形式标识运行时库的类型.

      这样的宏并不漂亮,但它们的优点是确保它们用来定义的所有东西都保持同步 [e.g.确保添加或删除acme_struct 的元素将导致它从存储在acme_struct_info] 中的结构成员列表中添加或删除。

      【讨论】:

        【解决方案5】:

        跟踪使用 offsetof() 宏计算的字段偏移量。如果 structp 是指向结构实例的指针,并且字段 f 是具有偏移 offsetf 的 int,则 f 的值可以通过

        间接设置
        *(int *)((char *)structp + offsetf) = value;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-29
          • 1970-01-01
          • 2011-01-05
          • 2023-03-17
          相关资源
          最近更新 更多