【问题标题】:How to provide an option to a C library via a macro如何通过宏为 C 库提供选项
【发布时间】:2018-10-26 20:14:18
【问题描述】:

我有以下来源,名为 lcd.c

#include <stdio.h>
#include "lcd.h"

void print_mode(void)
{
  printf("%d\n",LCD_MODE);
}

标题lcd.h 包含LCD_MODE 的定义,如下所示。

#ifndef LCD_H
#define LCD_H

#include "util.h"

#ifndef LCD_MODE
#define LCD_MODE LCD_MODE_8BIT
#endif

void print_mode(void);

#endif /* LCD_H */

文件util.h包含

#ifndef UTIL_H
#define UTIL_H

#define LCD_MODE_8BIT 1
#define LCD_MODE_4BIT 0

#endif /* UTIL_H */

lcd.c 将作为某些库的一部分单独编译。我想将它与应用程序main.c 一起使用,如下所示。

#include "util.h"
#define LCD_MODE LCD_MODE_4BIT
#include "lcd.h"

int main(void)
{
  print_mode();
  return 0;
}

期望的结果是根据main.cLCD_MODE_4BIT 的定义打印0。但是,打印1 是因为头文件看到LCD_MODElcd.c 的预处理期间没有定义。我应该如何通过主应用程序将LCD_MODE 选项传递给print_mode()

【问题讨论】:

  • 你不能用-DLCD_MODE=LCD_MODE_4BIT 选项编译你的代码吗?如果没有,那你就卡住了。
  • 如果您需要在不重新编译库的情况下对其进行配置,请不要使用宏。
  • 您可以将选项作为参数传递:void print_mode(int lcd_mode);
  • @Jean-FrançoisFabre 理想情况下,我不想为每个用例重新编译lcd.c(即我想将它作为一些更大的静态库的一部分)。所以我不能使用命令行定义。我想没有别的办法了……
  • 预处理对lcd.o 中的值进行硬编码,所以是的,除非您创建set_mode 方法,否则您会被卡住

标签: c linker c-preprocessor


【解决方案1】:

如果您无法重新编译 lcd.c,则您无法在另一个源文件中使用宏,因为 lcd.o 已经具有硬编码的值。

您可以创建一个静态变量(默认为 LCD_MODE),您可以使用 setter 对其进行更改:

#include <stdio.h>
#include "lcd.h"

static int the_mode = LCD_MODE;

void print_mode(void)
{
  printf("%d\n",the_mode);
}

void set_mode(int new_mode)
{
   the_mode = new_mode;
}

lcd.h 应该包含新配置函数 BTW 的原型:

void set_mode(int new_mode);

然后在你的主要,你可以:

set_mode(LCD_MODE);

(或者把 LCD_MODE 宏放到任何地方,因为它什么都解决不了,而且会增加混乱)

【讨论】:

  • 击败我 :(
  • 我打败了你“你不能那样做”的回答,TBH :)
猜你喜欢
  • 2013-05-20
  • 2019-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-23
  • 2013-02-07
  • 1970-01-01
相关资源
最近更新 更多