【问题标题】:How to globally #define a preprocessor variable?如何全局#define一个预处理器变量?
【发布时间】:2018-01-05 17:34:40
【问题描述】:

我正在用 C++ 编写一个 Arduino 草图。我希望用户能够直接在sketch.ino 文件中#definea 常量来编译代码。 Arduino IDE 使用 g++ 编译器。

假设我们有三个文件:

sketch.ino
sketch.h
sketch.cpp

在我定义的 sketch.h 中

#define OPTION_1 0
#define OPTION_2 1
#define OPTION_3 2
#define OPTION_4 3
#define SLOW 0
#define FAST 1

然后用户在sketch.ino中定义MYOPTION:

#define MYOPTION OPTION_2

在sketch.h中我使用变量来定义宏:

#if MYOPTION == OPTION_1 | MYOPTION == OPTION_2
    #define SPEED FAST
#else
    #define SPEED SLOW
#endif

在 sketch.cpp 中,我使用它来改进时间关键代码:

MyClass::foo() {
    // do something
    #if SPEED == FAST
    // do more
    #if MYOPTION == OPTION_2
    // do something extra
    #endif
    #endif
    #if MYOPTION == OPTION_4
    // do something else
    #endif
    }

不幸的是,MYOPTION 的定义似乎无法在sketch.cpp 中被识别。但是,sketch.cpp 确实可以识别sketch.h 中定义的变量。有没有办法全局定义预处理器变量,以便可以在任何使用它们的文件中访问它们?

【问题讨论】:

  • 您使用的g++ 编译器在优化方面有多出色?您可能希望避开所有这些预处理器垃圾并让您的编译器处理它,因为使用标准的ifenum 可以完成所有这些工作,并且减少很多混乱。通常最好使用const 而不是#define
  • @tadman 预处理器不可能优化我的代码。该代码是自定义的,基于附加的硬件。用户提供的选项决定了该硬件需要时间关键功能的哪些部分。因为(在这种情况下)一个 Arduino Due 的内存限制,提供几个函数是没有意义的。
  • MYOPTION 的定义与等号看起来很可疑。
  • @RobertPrévost 我的错。它在实际代码中没有等号。
  • 我的意思是 if (false) 块内的代码将被任何优化编译器删除。如果该块中的代码无法在某些平台上编译,您真的只需要实际的 #ifdef 类型块。

标签: c++ arduino g++ global preprocessor


【解决方案1】:
  • 将选项定义移动到单独的文件中,例如选项.h。如果您愿意,也可以在 sketch.ino 中定义它们。
  • 在 sketch.ino 和 sketch.h 中包含 options.h。
  • 将所有依赖于MYOPTION 宏的代码从sketch.cpp 移至sketch.h。
  • 在包含sketch.h之前在sketch.ino中定义MYOPTION
#include "options.h"
#define MYOPTION OPTION_2
#include "sketch.h"

这是一个使用这种技术的流行库的示例:

https://github.com/PaulStoffregen/Encoder

它允许用户通过ENCODER_DO_NOT_USE_INTERRUPTSENCODER_OPTIMIZE_INTERRUPTS 宏从草图配置中断的使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-10
    • 1970-01-01
    • 1970-01-01
    • 2015-02-27
    相关资源
    最近更新 更多