ESP8266/Arduino IDE中原有可用库突然报错的原因及修复方案
问题
我正在开发一款读取4x4矩阵键盘、并根据按键向本地服务器发送HTTP GET请求的程序,使用ESP8266 NodeMCU v3模块及Arduino IDE开发,却遭遇编译错误。此前这些库均可正常使用,且我未对相关内容进行明显改动。编译错误信息如下:
In file included from C:\Users\jacob\AppData\Local\Temp\arduino-sketch-370583BB0D9E467723E0BFBE6D37A087\sketch\Jan11.ino.cpp:1: C:\Users\jacob\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.0\cores\esp8266/Arduino.h:45:14: error: expected identifier before numeric constant 45 | #define HIGH 0x1 | ^~~ c:\Users\jacob\Documents\Arduino\libraries\Keypad\src/Keypad.h:56:16: note: in expansion of macro 'HIGH' 56 | #define CLOSED HIGH | ^~~~ C:\Users\jacob\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.0/tools/sdk/lwip2/include/lwip/tcpbase.h:57:3: note: in expansion of macro 'CLOSED' 57 | CLOSED = 0, | ^~~~~~ C:\Users\jacob\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.0\cores\esp8266/Arduino.h:45:14: error: expected '}' before numeric constant 45 | #define HIGH 0x1 | ^~~ c:\Users\jacob\Documents\Arduino\libraries\Keypad\src/Keypad.h:56:16: note: in expansion of macro 'HIGH' 56 | #define CLOSED HIGH | ^~~~ C:\Users\jacob\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.0/tools/sdk/lwip2/include/lwip/tcpbase.h:57:3: note: in expansion of macro 'CLOSED' 57 | CLOSED = 0, | ^~~~~~ In file included from C:\Users\jacob\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.0\cores\esp8266/wl_definitions.h:73, from C:\Users\jacob\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:28, from C:\Users\jacob\Documents\Arduino\Jan11\Jan11.ino:2: C:\Users\jacob\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.0/tools/sdk/lwip2/include/lwip/tcpbase.h:56:16: note: to match this '{' 56 | enum tcp_state { | ^ In file included from C:\Users\jacob\AppData\Local\Temp\arduino-sketch-370583BB0D9E467723E0BFBE6D37A087\sketch\Jan11.ino.cpp:1: C:\Users\jacob\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.0\cores\esp8266/Arduino.h:45:14: error: expected unqualified-id before numeric constant 45 | #define HIGH 0x1 | ^~~ c:\Users\jacob\Documents\Arduino\libraries\Keypad\src/Keypad.h:56:16: note: in expansion of macro 'HIGH' 56 | #define CLOSED HIGH | ^~~~ C:\Users\jacob\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.0/tools/sdk/lwip2/include/lwip/tcpbase.h:57:3: note: in expansion of macro 'CLOSED' 57 | CLOSED = 0, | ^~~~~~ In file included from C:\Users\jacob\Documents\Arduino\Jan11\Jan11.ino:2: C:\Users\jacob\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:29:1: error: expected declaration before '}' token 29 | } | ^ exit status 1 Compilation error: exit status 1
我已尝试重装部分库,但错误仍未消除。请问该问题由何导致?是否因函数使用错误引发库内部编译异常?有哪些修复建议?
问题原因
这是宏定义命名冲突导致的编译错误,和你代码里的函数使用无关,完全是库之间的预编译冲突:
- Keypad库在
Keypad.h第56行定义了#define CLOSED HIGH,而HIGH又被Arduino核心定义为0x1; - ESP8266 SDK里的lwIP网络库在
tcpbase.h第57行有一个tcp_state枚举,其中包含名为CLOSED的枚举成员; - 预编译阶段,编译器会把所有
CLOSED宏替换成0x1,导致枚举代码变成0x1 = 0,,这完全不符合C++语法,直接触发编译错误。
之前能正常编译可能是因为库的引入顺序不同,或者SDK/库的版本更新后引入了这个冲突。
修复建议
方法1:修改Keypad库的宏名
直接修改Keypad库的Keypad.h文件:
- 找到
#define CLOSED HIGH这一行,把CLOSED改成唯一的名字,比如KEYPAD_CLOSED; - 同时在库的
.cpp文件里,把所有用到CLOSED的地方也替换成新的宏名; - 你的代码里如果用到了
CLOSED(比如判断按键状态),也要同步改成新的名字。
方法2:调整库的引入顺序
在你的.ino文件里,先引入ESP8266WiFi库,再引入Keypad库:
#include <ESP8266WiFi.h> #include <Keypad.h> // 其他库引入...
这样编译器会先处理lwIP的枚举,再处理Keypad的宏,避免宏替换破坏枚举定义。
方法3:手动取消宏定义
在引入Keypad库之后,立即取消CLOSED宏的定义,避免影响后续的网络库代码:
#include <Keypad.h> #undef CLOSED // 取消Keypad的CLOSED宏定义 #include <ESP8266WiFi.h>
注意:如果你的代码里需要用Keypad的CLOSED状态,要改成直接用HIGH代替,或者自己重新定义一个宏:
#define KEYPAD_CLOSED HIGH
方法4:替换为无冲突的键盘库
如果不想修改现有库,可以换用其他矩阵键盘库,比如KeypadPlus或者直接自己实现矩阵键盘的扫描逻辑,避免宏定义冲突。
内容的提问来源于stack exchange,提问作者Jacob S. Crawford
相关产品推荐
相关产品推荐

