在C中的运行时期间使用#define宏值替换字符串

时间:2015-02-25 00:09:33

标签: c macros runtime c-preprocessor

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

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

Reg1 0x12345678

在test.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。

有没有办法实现这个目标?主要要求是用户生成的文件具有定义宏字符串而不是实际地址值。

1 个答案:

答案 0 :(得分:1)

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

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