#define from main (.ino) не учитывается компилятором в собственных библиотеках

У меня проблема, что мой #define from main (.ino) не учитывается компилятором в моих собственных библиотеках. Этот #define MQTT_MODULE рассматривается только в основной (.ino) программе, но не в MyRemoteLib.cpp. Этот пример работает нормально, если я скомпилирую его с помощью gcc.

Код в моем Test.ino:

#define         MQTT_MODULE             1
#include        "MyRemoteLib.h"
loop() {
  my_test() ;
}

Код в MyRemoteLib.h

#define     MYREMOTELIB_H
#define     MY_TEST         1
#if         MQTT_MODULE
  #define       MQTT_MOD_R              1
#endif

Код в MyRemoteLib.cpp:

#include        "MyRemoteLib.h"
void my_test() {
  #if   MQTT_MOD_R
      test.... > nothing -> ignored by compiler
  #endif
  #if   MQTT_MODULE
      test.... > nothing -> ignored by compiler
  #endif
  #if   MYTEST
      test.... > error-> not ignored by compiler
  #endif
}

, 👍0

Обсуждение

Ваш подход использования #define для выборочного включения различных частей вашей библиотеки обречен на провал, потому что он не работает таким образом. Возможно, вы захотите узнать больше о том, как создать «настоящую» библиотеку. Короче говоря, разделите все части на их собственный источник. Когда компоновщик разрешает ссылки, он добавит только необходимые модули. Однако, если это выполнимо с Arduino IDE, это другой вопрос., @the busybee


1 ответ


2

Это ожидаемое поведение. Библиотека и основная программа две разные единицы компиляции: там обрабатываются компилятором отдельно.

В основной программе включение заголовочного файла дает следующее:

#define         MQTT_MODULE             1
// Включено из MyRemoteLib.h:
#define     MYREMOTELIB_H
#define     MY_TEST         1
#if         MQTT_MODULE
  #define       MQTT_MOD_R              1
#endif
// конец включаемого кода
loop() {
  my_test() ;
}

Остальной код препроцессора не имеет никакого эффекта.

В библиотеке такое же включение дает следующее:

// Включено из MyRemoteLib.h:
#define     MYREMOTELIB_H
#define     MY_TEST         1
#if         MQTT_MODULE
  #define       MQTT_MOD_R              1
#endif
// конец включаемого кода
void my_test() {
  #if   MQTT_MOD_R
      test.... > nothing -> ignored by compiler
  #endif
  #if   MQTT_MODULE
      test.... > nothing -> ignored by compiler
  #endif
  #if   MYTEST
      test.... > error-> not ignored by compiler
  #endif
}

Условная компиляция дает пустой my_test() (то есть, если под MYTEST вы на самом деле подразумеваете MY_TEST).

Я не знаю, чего вы пытаетесь достичь, но вы можете поискать способы разместить код для условной компиляции в самом заголовке. Ты можете попробовать использовать встроенные функции или шаблоны.

ОБНОВЛЕНИЕ: об удалении кода с помощью условной компиляции: это не всегда полезно, как это может показаться, по двум причинам.

  1. По умолчанию среда разработки Arduino IDE компилирует ваш код с параметрами -ffunction-sections и -fdata-sections и связывает его с -Wl,--gc-sections. Это означает, что любая функция или метод, никогда не используется, или любая глобальная переменная, на которую никогда не ссылаются, не является включены в окончательный исполняемый файл.

  2. Код также скомпилирован с помощью -flto, что позволяет связать время (полная программа) оптимизации. Это означает, что код, который зависит при условии, которое всегда ложно (условное выражение может разрешаться как константа времени компиляции) также удаляется из окончательный исполняемый файл.

,

Спасибо за ответ. Что ж, я пытаюсь создать универсальный код в своей собственной библиотеке, чтобы я мог «активировать» «модуль» в своей основной программе. И я думал, что препроцессор - лучший способ, поэтому он даже не будет выполнен (если он мне не нужен). Например, некоторые сенсорные функции должны отправлять mqtt msg только в том случае, если я активирую свой «модуль Wi-Fi»… в противном случае компилятор также жалуется! Вот почему я предпочитаю использовать #define. Также, если я использую «обычный» компилятор gcc, он работает., @stevo

@stevo Что-то из этого, вероятно, предназначено как комментарий к ответу Эдгара Боне, а что-то *может* быть чем-то, что должно быть отредактировано в вопросе. Будьте осторожны, чтобы не отредактировать вопрос из-под существующего ответа. Это не форум. Как это должно работать, так это то, что есть вопросы с соответствующими ответами. Не ветка форума., @timemage

@stevo Я сомневаюсь, что ваш «обычный» gcc работает по-другому и «видит» #define в источнике другой единицы перевода. Кстати, компилятор, используемый Arduino IDE, тоже является gcc., @the busybee