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

Posted

技术标签:

【中文标题】在 C 中运行时用#define 宏值替换字符串【英文标题】:Substitute string with #define macro value during runtime in C 【发布时间】:2015-04-26 20:17:31 【问题描述】:

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

在用户定义的文件'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 调用转换为 write(0x400000000, 0x12345678) 然而,由于这些#define 在编译时被替换,它没有生效。另外,由于我对字符串进行了类型转换,因此它通过了编译和详细说明,替换了字符串的 int 等效项。

有没有办法做到这一点?主要要求是用户生成的文件定义了宏字符串而不是实际的地址值。

【问题讨论】:

你的main()签名错误,可以是int main(),但不只是main()没有任何返回类型。 我对字符串进行了类型转换,它通过了编译和细化,替换了字符串的 int 等效项 什么? 使用 strtol() 并将基址 16 传递给它。而且,write() 是一个标准函数,它需要 2 个 int's 我猜不出你真正需要什么,因为你要求的是时间旅行。无论你从文件中得到什么,都是在运行时,在像#define 这样的编译时东西消失很久之后。你真正想做的是什么?以某种方式处理文件,以某种形式产生输出?请尽量具体,尽量不要谈论语言或细节——只是你想做的。 Reg1 不等于 reg1 【参考方案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 );

【讨论】:

以上是关于在 C 中运行时用#define 宏值替换字符串的主要内容,如果未能解决你的问题,请参考以下文章

用 C 编写的 UEFI 二进制文件在 UEFI 中运行时不会选择文本文件

顺序并在一个线程中运行时差c ++ [关闭]

C语言中#define的用法(转)

在调试器中运行时中断下一个输出

在 jupyter notebook 中运行时出错

php中const和define的区别