You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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]是运行时动态获取的字符串),因此直接传入变量会触发编译错误。

修正步骤

  1. 创建字体指针数组
    直接存储字体的指针(而非字体名称字符串),因为每个字体本质是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标记了内存段属性,我们无需再次使用该宏,直接引用指针即可。

  2. 切换字体
    直接将数组中的指针传入setFont函数:

    u8g2.setFont(fonts[pos]);
    
  3. 批量处理字体的技巧
    若字体数量过多,手动声明麻烦:

    • 可在PlatformIO的platformio.ini中添加U8G2的字体编译选项,自动引入指定类别的字体;
    • 借助预处理器批量生成字体指针数组,减少重复代码。

额外注意

确保所有用到的字体都被编译链接到程序中,避免出现undefined reference错误。如果使用U8G2的自动字体包含功能,需在代码开头定义对应的宏(比如U8G2_FONT_TABLE_ALL)来引入所有字体。

内容的提问来源于stack exchange,提问作者Franziee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 10:44:54