【问题标题】:Include the same header file in multiple files - 'variable' was not declared in this scope在多个文件中包含相同的头文件 - 在此范围内未声明“变量”
【发布时间】:2019-03-06 19:35:43
【问题描述】:

我对以下代码有疑问(这些只是 sn-ps,不是完整文件):

菜单.h

#ifndef MENU_H
#define MENU_H

#include <Adafruit_SSD1306.h>
#include <stdint.h>

#include <Config.h>

class MenuHeader; // forward declaration of class MenuHeader
class MenuPage; // forward declaration of class MenuPage

class Menu {
    MenuHeader* m_header{nullptr};
    MenuPage* m_pages[16]{}; // support up to 16 pages
    uint8_t m_pagesCount{0};
    uint8_t m_currentPage{0};

    public:
    void setHeader(MenuHeader* header);
    void addPage(MenuPage* page);
    void goToPage(const char* pageName);
    void next();
    void prev();
    void click();
    void draw(Adafruit_SSD1306* display);
};

#endif

菜单.cpp

#include <Menu.h>
#include <MenuHeader.h>
#include <MenuPage.h>

/* Some other definitions */

void Menu::draw(Adafruit_SSD1306* display) {
    if(m_header != nullptr) {
        display->setCursor(0, HEADER_HEIGHT - 1 + SCREEN_Y_OFFSET);
        m_pages[m_currentPage]->draw(display);
        m_header->draw(display);
    } else {
        display->setCursor(0, SCREEN_Y_OFFSET);
        m_pages[m_currentPage]->draw(display);
    }
}

配置.h

#ifndef CONFIG_H
#define CONFIG_H

#include <stdint.h>

constexpr uint8_t ENCODER_PIN_A = 14; // pin A of rotary encoder
constexpr uint8_t ENCODER_PIN_B = 12; // pin B of rotary encoder
constexpr uint8_t BUTTON_PIN = 13; // pin to which button is connected

constexpr uint8_t SCREEN_WIDTH = 128; // width of screen in pixels
constexpr uint8_t SCREEN_HEIGHT = 64; // height of screen in pixels
constexpr uint8_t CHARS_PER_LINE = 18; // how many characters fit in one line
constexpr uint8_t CHAR_WIDTH = SCREEN_WIDTH/CHARS_PER_LINE; // width of single character
constexpr uint8_t CHAR_HEIGHT = 10; // height of single char
constexpr uint8_t SCREEN_Y_OFFSET = CHAR_HEIGHT; // screen offset, if not using custom font set to 0

constexpr uint8_t HEADER_HEIGHT = 14; // menu header height in pixels

constexpr int8_t TIMEZONE = -1; // timezone

/* Some other not needed stuff */

#endif

所有标题(Menu.h、MenuHeader.h、MenuPage.h)都包括 Config.h。

好吧,编译器似乎不喜欢它。它抛出:

'HEADER_HEIGHT' was not declared in this scope
identifier "HEADER_HEIGHT" is undefined
'SCREEN_Y_OFFSET' was not declared in this scope
identifier "SCREEN_Y_OFFSET" is undefined

所有关于 Menu.cpp 文件的内容。 我认为如果我将 Config.h 文件包含在我的 Main.cpp 中的一个标头中,它应该可以工作。即使我直接在 Main.cpp 中包含配置 - 也会发生相同的错误。我该怎么办?

编辑: 嗯,奇怪的事情正在发生。如果我在 Menu.h 中有 #include &lt;Config.h&gt;,则配置仅适用于该文件。如果我将其更改为#include "../Config/Config.h",它可以在 Menu.h 和 Menu.cpp 中使用。这是怎么回事? My folder structure 使用&lt;Config.h&gt; 是platformio 的功能。它会自动找到所有库并编译它们。

【问题讨论】:

  • 为什么是constexpr 而不是const 只是简单的常量值?
  • 都试过了。两者都不起作用。我只是认为 constexpr 在我的情况下可能会更好。
  • 我的猜测 - 其他一些标头已经定义了 CONIFG_H,试试 CONFIG___H
  • 正如@pm100 指出的那样,您可能在这里遇到命名空间冲突。现在是 2018 年,您可能还想检查您的编译器是否支持 #pragma once 以避免所有这些 #ifndef 废话。
  • 如果它不理解自 1970 年代以来一直存在的 "..." 风格,该扩展听起来要么配置错误,要么超级损坏。

标签: c++ arduino platformio


【解决方案1】:

发现一个问题。原来 Config 可能是保留名称,这就是它不起作用的原因。将名称更改为 CFG 解决了问题。感谢您的宝贵时间。

【讨论】:

  • 是另一个名为“Config.h”的文件还是已经定义的宏“CONFIG_H”?
  • 没有。我没有任何名为 Config.h 的文件,并且我将所有 ifndefs 更改为 Pragma 一次。只有更改名称有帮助。
  • 所以在包含的一个包含目录中还有另一个“Config.h”文件,而不是您的头文件。
  • 刚刚检查过。你说得对。 esp8266 库有一个 Config.h 文件。我没有注意到它,因为那个 lib 不在我的工作目录中。虽然我不知道为什么它有时会起作用
  • 看我的回答。使用 "" 而不是 来包含文件的本地版本而不是系统包含目录之一中的文件。
【解决方案2】:

这看起来不正确:

#include <Config.h>

您正在包含来自系统包含路径的Config.h
我假设您想从应用程序包含路径中包含一个Config.h

#include "Config.h" // Note the quotes rather than the < >

检查包含路径的位置:

https://stackoverflow.com/a/11946295/14065

查看两组路径中是否有另一个“Config.h”。

另请注意:

这看起来也不对:

#include <stdint.h>

这是为了包含整数类型的 C 版本。这不太可能将这些定义正确地放在std 中。

<cstdint> vs <stdint.h>

您应该使用正确的 C++ 头文件:

#include <cstdint>

【讨论】:

  • 是正确的,我使用为我编译库的 PlatformIO 扩展。感谢您指出 cstdint 的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-18
  • 2017-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多