c - 在 C 中的运行时用 #define 宏值替换字符串

标签 c macros runtime c-preprocessor

我一直在尝试寻找一种在运行时使用宏定义字符串作为它们的值的方法。我的测试场景是这样的

在用户定义的文件 'data.txt' 中

Reg1 0x12345678

在测试.c中

extern write(uint64_t addr, uint32_t value);

main(){
  FILE * reg_data;
  char reg_name[256];
  uint32_t value;

  reg_data = fopen("data.txt", "r");
  if(reg_data == NULL){
    print_log("Cannot open file data.txt\n");
    exit(-1);
  }
  while(fscanf(reg_data, "%s %x \n", reg_name, value) != EOF){
    write((uint64_t)reg_name, value);
  }     
}

在另一个包含文件'head.h'中

#define reg1 0x400000000

所以我希望我的写入调用转换为 write(0x400000000, 0x12345678) 然而,由于这些 #define 在编译时被替换,所以它没有生效。此外,由于我对字符串进行了类型转换,因此它通过了编译和详细说明,替换为字符串的 int 等价物。

有什么办法可以实现吗?主要要求是用户生成的文件具有定义宏字符串而不是实际地址值。

最佳答案

您需要的是一个查找表,其中包含寄存器的名称和相应的整数值。这是一个示例查找表,其中包含两个寄存器的条目

#define reg1 0x40000000
#define reg2 0x40000010

typedef struct
{
    const char *name;
    uint64_t value;
}
    stLookup;

static stLookup lookup[] =
{
    {  "reg1", reg1  },
    {  "reg2", reg2  },
    {   NULL , 0     }
};

然后你需要一个函数,它接受一个字符串,在表中找到相应的条目,并返回值。下面的示例函数将返回值,如果在表中找不到该名称,则返回 0

uint64_t addrForName( const char *name )
{
    stLookup *lptr;

    for ( lptr = lookup; lptr->name != NULL; lptr++ )
        if ( strcmp( lptr->name, name ) == 0 )
            break;

    return( lptr->value );
}

你可以这样调用函数

uint64_t addr = addrForName( reg_name );

关于c - 在 C 中的运行时用 #define 宏值替换字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28708832/

相关文章:

c - 错误的宏定义导致 "Expected expression"错误

c - 未使用的宏警告

java - 使用向后兼容性编译的 java 类是否使用更新版本的 JavaVM 优化?

c - 为什么我不能将两个字符串组合在一起?

c - 在 C 中定义 "between"宏的最佳方式

java - 我可以在运行时在 netbeans 的 jframe 中添加组件吗?

java - SearchEventListener 不是抽象的,不会重写抽象方法 actionPerformed

c - printf %f 地址错误

c - 为什么弱类型在C中实现垃圾回收是 "impossible"?

c - 使用 scanf 读取特定单词