簡體   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