【问题标题】:Create Compile Time Variable Offset Map创建编译时变量偏移贴图
【发布时间】:2017-11-28 19:49:00
【问题描述】:

我正在尝试在 C 中查找结构的变量名称。示例:

def.h

typedef struct
{
    int fov_one;
    int fov_two;
    int timing_chain;
    ...
    ...
    float ratio;
    float spare_floats[15];
}PARAMETERS;

该结构最多可容纳 200 个参数,但目前只有部分参数在使用。目前,结构 PARAMETERS 中的值由二进制文件填充。但是,一些用户希望在填充后在运行时更改其中的一两个值。我想创建基于变量名的字符串版本更改值的选项。例如,如果我想更改变量比率,我希望用户能够输入字符串“ratio .25”并将“ratio”的当前值替换为“.25”。

根据我的阅读,由于没有反射,因此无法根据 C 中变量名称的字符串版本找到变量。目前,我的想法是解析标头以获取变量名称,但有人提到可能在将名称剥离之前从链接器获取名称。据我了解,编译器/链接器在编译期间删除了变量名,并使用地址来访问变量,而不是符号。

我想知道是否可以打印出包含编译器/链接器创建的变量名称和偏移量的符号映射。

使用 gcc 选项

gcc -o foo foo.c -Wl,Map,foo.map

创建一个映射,但不包含结构的变量名。

是否可以提取编译器/链接器在编译时创建的变量偏移映射?

【问题讨论】:

  • 字段的名称在编译时是已知的,因此您需要创建一个函数来了解这 200 个字段中的每一个以及用于更新它们并将它们映射在一起的关键字。

标签: c gcc gdb


【解决方案1】:

结构偏移可作为 DWARF 输出(或目标用户的任何调试格式)的一部分使用。它们也可用于编译器插件。

但是,编写或生成基于字符串更新PARAMETERS 对象的直接代码可能更容易。您可以通过列出字段名称的字符串及其offsetof 值来创建更紧凑的表示。

【讨论】:

  • 另外,在用户级别,似乎至少有一些成员的名称可能比代码中使用的名称更好。我不想记住“
【解决方案2】:

由于您控制源代码,因此常用的技术是在编译时生成“名称到偏移”映射。

例如:

// parameter_fields.inc -- describes fields in struct PARAMETERS
xxx(int, fov_one)
xxx(int, fov_two)
...
xxx(float, ratio)

// def.h
struct _PARAMETERS {
 #define xxx(a, b) a b;
  #include "parameter_fields.inc"
 #undef xxx
} PARAMETERS;

// in somefile.c
#include <stddef.h>
#include "def.h"

struct {
  const char *name;
  int offset;
} PARAMETER_OFFSETS[] = {
 #define xxx(a, b)  #b, __offsetof__(struct _PARAMETERS, b),
  #include "parameter_fields.inc"
 #undef xxx
};

现在,您的代码可以随时使用偏移量作为PARAMETER_OFFSETS 数组的一部分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-24
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    相关资源
    最近更新 更多