基于PlatformIO与U8G2的ESP8266字体数组编译错误解决
问题描述
借助PlatformIO和U8G2库为ESP8266编写应用,目标是遍历显示U8G2的数千种字体以筛选合适的字体。
字体定义格式如下:
extern const uint8_t u8g2_font_logisoso50_tn[] U8G2_FONT_SECTION("u8g2_font_logisoso50_tn");
相关宏定义:
#define U8G2_FONT_SECTION(name) U8X8_FONT_SECTION(name) ... # define U8X8_FONT_SECTION(name) __attribute__((section(".text." name))) ... typedef __uint8_t uint8_t ; ... typedef unsigned char __uint8_t ;
字体通过void setFont(const uint8_t *font)函数设置显示。创建了字体名称字符串数组:
const char* fonts[] = { "u8g2_font_u8glib_4_tf", ... };
尝试通过u8g2.setFont( U8G2_FONT_SECTION(fonts[pos]) );切换字体时,编译器报错:
In file included from .pio\libdeps\d1\U8g2\src/U8x8lib.h:47, from .pio\libdeps\d1\U8g2\src/U8g2lib.h:53, from src\main.cpp:2: src\main.cpp: In function 'void put()': .pio\libdeps\d1\U8g2\src/clib/u8x8.h:162:35: error: expected primary-expression before '__attribute__' 162 | # define U8X8_FONT_SECTION(name) __attribute__((section(".text." name))) | ^~~~~~~~~~~~~ .pio\libdeps\d1\U8g2\src/clib/u8g2.h:188:33: note: in expansion of macro 'U8X8_FONT_SECTION' 188 | #define U8G2_FONT_SECTION(name) U8X8_FONT_SECTION(name) | ^~~~~~~~~~~~~~~~~ src\main.cpp:18:20: note: in expansion of macro 'U8G2_FONT_SECTION' 18 | uint8_t font[] = U8G2_FONT_SECTION(fonts[pos]); | ^~~~~~~~~~~~~~~~~ *** [.pio\build\d1\src\main.cpp.o] Error 1
解决方案
错误原因
U8G2_FONT_SECTION是编译期宏,仅能处理编译时确定的字符串字面量,无法识别运行时才会确定的变量(比如fonts[pos]是运行时动态获取的字符串),因此直接传入变量会触发编译错误。
修正步骤
创建字体指针数组
直接存储字体的指针(而非字体名称字符串),因为每个字体本质是const uint8_t[]类型的数组,我们需要引用它的地址:// 先声明要用到的所有字体(U8G2库的字体头文件已包含这些extern声明,若未自动包含可手动添加) extern const uint8_t u8g2_font_u8glib_4_tf[]; extern const uint8_t u8g2_font_logisoso50_tn[]; // 更多字体声明... // 创建字体指针数组 const uint8_t* fonts[] = { u8g2_font_u8glib_4_tf, u8g2_font_logisoso50_tn, // 其他字体指针... };注:U8G2的字体定义已经通过
U8G2_FONT_SECTION标记了内存段属性,我们无需再次使用该宏,直接引用指针即可。切换字体
直接将数组中的指针传入setFont函数:u8g2.setFont(fonts[pos]);批量处理字体的技巧
若字体数量过多,手动声明麻烦:- 可在PlatformIO的
platformio.ini中添加U8G2的字体编译选项,自动引入指定类别的字体; - 借助预处理器批量生成字体指针数组,减少重复代码。
- 可在PlatformIO的
额外注意
确保所有用到的字体都被编译链接到程序中,避免出现undefined reference错误。如果使用U8G2的自动字体包含功能,需在代码开头定义对应的宏(比如U8G2_FONT_TABLE_ALL)来引入所有字体。
内容的提问来源于stack exchange,提问作者Franziee
相关产品推荐
相关产品推荐

