繁体   English   中英

在ifdef块中对函数的未定义引用

[英]undefined reference to function inside ifdef block

我有以下问题:

我正在为一个与微控制器一起使用的传感器编写一个收集库。 意思是我在传感器项目中使用了大量的库来进行抽象,并在一个统一的库中对其进行简化,以简化学生项目。

我使用#define结构确定学生要使用和连接的传感器。

例:

#define IR_SENSOR_USED

然后,在库的.h和.cpp文件中,我使用#ifdef #endif对来定义和声明给定传感器的功能,并包括给定库。

我的Sensors.h文件中的示例:

#ifdef IR_SENSOR_USED
  #include "SparkFun_GridEYE_AMG88/src/SparkFun_GridEYE_Arduino_Library.h"
  extern GridEYE grideye;
  void setup_ir_sensor();
  void read_ir_sensor();
  void enable_ir_interrupt(float lower, float upper, float hysteresis);
  void disable_ir_interrupt();
#endif

并从我的Sensors.cpp文件中:

#ifdef IR_SENSOR_USED
void setup_ir_sensor() {
  Wire.begin(16, 17, 0x69);
  grideye.begin(0x69, Wire);
}

void read_ir_sensor() {
  for (int i = 0; i <= 64; i++) {
    sensor_values.ir_pixel_temp[i] = grideye.getPixelTemperature(i);
  }
  sensor_values.ir_device_temp = grideye.getDeviceTemperature();
}

void enable_ir_interrupt(float lower, float upper, float hysteresis) {...}

void disable_ir_interrupt() {...}
#endif

但是,只要我在.cpp文件中有#ifdef ,如果尝试在setup()调用该函数,就会收到以下错误:

sketch/Sensors.ino.cpp.o:(.literal._Z5setupv+0xc): undefined reference to `read_ir_sensor()'
sketch/Sensors.ino.cpp.o: In function `setup()':
.../Sensors/Sensors.ino:112: undefined reference to `read_ir_sensor()'
collect2: error: ld returned 1 exit status
exit status 1

如果我将它们注释掉,则代码可以正常执行。 另一个函数( setup_sensors() )也可以在Sensors.h.cpp文件中使用,并且不被#ifdef包围。

这是我的Sensors.ino草图:

#define IR_SENSOR_USED
//#define COLOR_SENSOR_USED
//#define ENV_SENSOR_USED
//#define TEMP_SENSOR_USED

#include "Sensors.h"

void setup() {
  sensor_setup();

  read_ir_sensor();
}

void loop() {
}

这是什么原因? (为什么)预处理器不能正确执行.cpp文件中的指令?

这个问题可能是XY问题的一个实例。

如果您希望库的用户选择他们需要的功能,则将声明放在单独的标头中会更有意义。 例如, IR_sensor.h ,然后

#define IR_SENSOR_USED
#include "Sensors.h"

变成只是#include "IR_sensor.h"

  • 如果需要考虑库的大小,则可以将其拆分为单独的库。

  • 第三种选择是将功能提供为仅标头的库。

确切答案:

这是什么原因? (为什么)预处理器不能正确执行.cpp文件中的指令?

最可能的原因是Sensors.cpp不知道#define IR_SENSOR_USED 定义在另一个未包含的文件中。

但是,即使在IR_SENSOR_USED中定义了Sensors.cpp出现另一个问题:必须为定义的每种可能的组合重新编译Sensors.cpp 否则,ifdefed-code将从编译中排除,并且不能通过调用#define在客户端简单地启用。

正如注释和其他答案所指出的那样,任何#define指令仅在包含它们的文件中可见。 所以有

#define IR_SENSOR_USED

Sensors.cpp代码不会影响未在Sensors.cpp编译的任何代码(重要的是,它会影响#define之后在Sensors.cpp包含的.h文件中包含的Sensors.cpp 。但不会影响其中包含的任何内容。在另一个.cpp文件中。

比Arduino更复杂的构建环境具有更好和更复杂的方法来解决此问题,但是Arduino世界并没有为您提供很多工具来解决这一问题。

我在Arduino世界中所做的只是有一个名为config.h ,其中包含我在项目范围内需要的所有#define语句。 我在每个需要这些值的文件中包含#include "config.h"

因此,在您的情况下,应将所有定义显示在config.h中使用哪些设备,然后在每个依赖它的文件的开头#include "config.h"

您甚至可以将其包括在Sensors.h文件的开头。 我会考虑将两个文件分开,以便在需要配置的内容和有用的代码之间有明确的界限。

我还将所有敏感值(wifi凭据,密码,API密钥)保留在此文件中,并将其从我在Github上发布的代码中排除。 在其中,我包括一个“ config-example.h”文件,该文件中包含所有伪指令,但带有伪值,以便其他使用该代码的人可以对其进行编辑和重命名。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM