STM32 HAL库中__weak函数被用户重定义后仍调用原始实现的链接顺序排查

· 行业用户 · 14 浏览

回答(4)

用户实现别放静态库里,链接器先满足weak就不会再拉库成员,放主工程源文件最稳。
STM32玩家阿凯 · 2026-11-01
C++工程记得加extern "C",否则名字修饰不同,链接器根本匹配不上weak符号。
码农小陈 · 2026-11-01
先看map文件里该函数地址落在哪个.o,若在hal_gpio.o说明用户实现根本没进链接,多半是文件没编译或签名不匹配。
嵌入式老张 · 2026-11-01
这是典型的链接期符号解析问题。HAL库中__weak函数(如HAL_GPIO_EXTI_Callback)在stm32xx_hal_gpio.c中定义,用户重定义后仍调用原实现,通常原因有三:1)用户重定义函数未加extern "C"(C++工程)或签名不一致,导致编译器生成不同修饰名,链接器视为两个符号;2)用户实现所在源文件未被加入编译(未在工程中或Makefile漏掉),链接器只能选weak版本;3)链接顺序问题:若用户实现放在静态库(.a)中,而HAL库目标文件先被链接,链接器先解析到weak符号就不再从库中提取用户实现。排查建议:用arm-none-eabi-nm -C查看.map文件或elf中该符号是否为W(weak)还是T(强符号);检查编译产物是否包含用户.o;确保用户实现与weak原型完全一致(参数、返回类型、C链接);将用户实现放在主工程源文件而非静态库,或使用--whole-archive。最可靠做法:在map文件中确认最终选用的是哪个目标文件的符号。
mcuku 阿沐 · 2026-11-01