在 main 之外编译 mDNS 功能时出错

Error compiling mDNS functionality when outside of main

当 mDNS 不是标准 setup() loop() 构造的一部分时,我遇到了问题。我可以把它留在 main 中,但是我还有其他我想做的处理,把它留在那儿会很混乱并且违反了 "one purpose, one file" 范例。另外,这让我发疯。

以下将编译并且 运行 没有错误:

main.h

#ifndef MAIN_H
#define MAIN_H

#include <WiFiManager.h>
#include <ESP8266mDNS.h>

void setup();
void loop();
void mdnssetup();

#endif // MAIN_H

main.cpp:

#include "main.h"

void setup() {
    WiFiManager wifiManager;
    mdnssetup();
}

void loop() {
    MDNS.update();
    yield();
}

void mdnssetup() {
    MDNS.begin(WiFi.hostname());
    MDNS.addService("http", "tcp", 80);
}

每当我将函数拉到一个单独的文件时,我都会出错。以下配置(我将 MDNS 设置分开)会产生错误:

main.h:

#ifndef MAIN_H
#define MAIN_H

#include "mdns.h"
#include <WiFiManager.h>

void setup();
void loop();

#endif // MAIN_H

main.cpp:

#include "main.h"

void setup() {
    WiFiManager wifiManager;
    mdnssetup();
}

void loop() {
    MDNS.update();
    yield();
}

mdns.h:

#ifndef MDNS_H
#define MDNS_H

#include <ESP8266mDNS.h>

void mdnssetup();

#endif // MDNS_H

mdns.cpp

#include "mdns.h"

void mdnssetup() {
    MDNS.begin(WiFi.hostname());
    MDNS.addService("http", "tcp", 80);
}

以下是我在后面的设置中收到的错误:

In file included from src\mdns.h:4:0,
                 from src\main.h:4,
                 from src\main.cpp:1:
C:\Users\foo\.platformio\packages\framework-arduinoespressif8266\libraries\ESP8266mDNS\src/ESP8266mDNS.h:52:27: error: expected type-specifier
     using MDNSResponder = esp8266::MDNSImplementation::MDNSResponder; //new
                           ^
C:\Users\foo\.platformio\packages\framework-arduinoespressif8266\libraries\ESP8266mDNS\src/ESP8266mDNS.h:54:12: error: 'MDNSResponder' does not name a type
     extern MDNSResponder MDNS;
            ^
src\main.cpp: In function 'void loop()':
src\main.cpp:9:5: error: 'MDNS' was not declared in this scope
     MDNS.update();
     ^
*** [.pio\build\d1_mini\src\main.cpp.o] Error 1
In file included from src\mdns.h:4:0,
                 from src\mdns.cpp:1:
C:\Users\foo\.platformio\packages\framework-arduinoespressif8266\libraries\ESP8266mDNS\src/ESP8266mDNS.h:52:27: error: expected type-specifier
     using MDNSResponder = esp8266::MDNSImplementation::MDNSResponder; //new
                           ^
C:\Users\foo\.platformio\packages\framework-arduinoespressif8266\libraries\ESP8266mDNS\src/ESP8266mDNS.h:54:12: error: 'MDNSResponder' does not name a type
     extern MDNSResponder MDNS;
            ^
src\mdns.cpp: In function 'void mdnssetup()':
src\mdns.cpp:4:5: error: 'MDNS' was not declared in this scope
     MDNS.begin(WiFi.hostname());
     ^
*** [.pio\build\d1_mini\src\mdns.cpp.o] Error 1

显然,我可以读取错误。我对这通常告诉我的内容有一个模糊的理解。但是,应用它告诉我的内容超出了我的理解范围。换句话说,请使用简短的词,请不要剪切和粘贴错误,就好像这是我在一些搜索中看到的解决方案一样。

通常最好只关注第一个 compiler-error 生成的,因为后一个 compiler-error 通常只是 follow-on 编译器被第一个错误弄糊涂的结果。所以:

 C:\Users\foo\.platformio\packages\framework-arduinoespressif8266\libraries\ESP8266mDNS\src/ESP8266mDNS.h:52:27: error: expected type-specifier
 using MDNSResponder = esp8266::MDNSImplementation::MDNSResponder; //new
                       ^

... 这里我们看到编译器遇到了标识符 esp8266 但不知道它是什么。事实上,它(很可能)是一个命名空间限定符,但似乎没有任何信息告诉编译器有关该命名空间的信息。我建议查看 header 文件,看看是否可以找到声明 namespace esp8266 的位置,如果可以,也许您可​​以先 #include 那个 header 文件(即在 mdns.h 文件的顶部附近),看看这是否有助于编译器。

另一种很可能的情况(假设您列出的 mdns.h 文件是您创建的文件,而不是 system-supplied 文件)是您的 mdns.h 文件具有完全相同的命名为 system-supplied mdns.h 文件,因此当 system-supplied header 尝试 #include "mdns.h" 他们最终得到的是你的文件,而不是他们期望的文件得到,这就是为什么他们不拉入他们所依赖的 namespace-definition 的原因。如果是这样,简单的解决方法是将 mdns.h 文件重命名为例如my_mdns.h 或与任何 system-supplied 包含文件拼写不同的其他内容。 (并且可能将您的 mdns.cpp 文件也重命名为 my_mdns.cpp 文件,只是为了保持一致)

您正在使用的 headers 之一 #include <ESP8266mDNS.h> 包括 #include "LEAmDNS.h"(参见 here), which in turn uses the same include guard as you (see here

所以要修复它,请将 mdns.h 中的 include guard 更改为不同于以下内容的内容:

#ifndef MDNS_H
#define MDNS_H

或在支持的情况下使用 #pragma once