使用typedef定义函数指针时报'redeclared as different kind of symbol'错误如何解决
错误成因
该编译错误的核心原因是同一作用域内同名符号被定义为完全不同的类型:
- 你在
UART_ATMEGA328.h中,将USART_Init、USART_SendString、USART_TxChar三个名字声明为全局函数原型 - 你在
sim900.h中,又将这三个相同的名字用typedef定义为函数指针类型
当某个C源文件同时包含这两个头文件时,编译器扫描到第二个同名符号定义时,发现和第一次定义的符号类型完全不一致(一个是函数本身,一个是指向函数的指针类型),就会抛出redeclared as different kind of symbol错误。
可行解决方案
方案1:修改SIM900抽象层的函数指针类型命名(最推荐,改动最小)
给SIM900模块内部使用的函数指针类型加专属前缀,避免和底层驱动的函数名冲突,不需要修改底层UART驱动代码。
修改后的sim900.h对应部分示例:
// 给函数指针类型加Sim900_前缀,避免和底层函数名冲突 typedef void (*Sim900_USART_Init)(unsigned long); typedef void (*Sim900_USART_SendString)(char*); typedef void (*Sim900_USART_TxChar)(char); typedef struct { Sim900_USART_Init start; Sim900_USART_SendString write; Sim900_USART_TxChar tx; //其他自定义成员 }Sim900_Config_t;
后续绑定底层驱动的时候,直接把UART对应的函数名赋值给结构体成员即可,完全不影响原本的硬件抽象逻辑。
方案2:修改底层UART驱动的函数命名
如果SIM900抽象层已经在多处使用,修改类型名成本更高,可以给底层UART驱动的函数加前缀,比如改成HAL_USART_Init、HAL_USART_TxChar等,同样可以解决冲突。这种方案的缺点是如果底层驱动已经在多个模块中调用,需要同步修改所有调用处的代码。
方案3:拆分头文件依赖
如果SIM900头文件本身不需要感知底层UART驱动的存在,仅在具体的初始化绑定逻辑的C文件中才需要同时引用两个头文件,也可以调整头文件包含逻辑,避免在同一个头文件中同时引入两个冲突的定义,不过这种方案适用场景有限,不如修改命名稳妥。
内容的提问来源于stack exchange,提问作者SHRAVAN SHETTY
相关产品推荐
相关产品推荐

