jjbboox 发表于 2018-3-12 14:55:01

求教:sw4stm32编译C++工程 Link的时候出错,请大神帮忙看看

是用STM32CubeMX生成的sw4stm32工程。
然后在sw4中转换为C++工程
建立了一个Source Folder 叫做user_libs,在该目录下添加了自定义的类。
该类中有一个public的function定义如下
void HW_SteerEngine::init(TIM_HandleTypeDef        *htim, uint32_t tim_channel, int angle)
C和C++编译设置中都已经把user_libs目录添加到include路径中。
代码编译都过了,最后在link的时候出现下列错误。

Building target: SteerEngine.elf
Invoking: MCU G++ Linker
arm-none-eabi-g++ -mcpu=cortex-m3 -mthumb -mfloat-abi=soft -specs=nosys.specs -specs=nano.specs -T"../STM32F103C8Tx_FLASH.ld" -Wl,-Map=output.map -Wl,--gc-sections -fno-exceptions -fno-rtti -o "SteerEngine.elf" @"objects.list"   -lm
Src/user_main.o: In function `user_setup':
D:\jinbin\单片机\MyProject\STM32\AC6 WorkSpace\SteerEngine\Debug/../Src/user_main.cpp:18: undefined reference to `HWSteerEngine::HW_SteerEngine::init(TIM_HandleTypeDef*, unsigned long, int)'
collect2.exe: error: ld returned 1 exit status
make: *** Error 1
makefile:51: recipe for target 'SteerEngine.elf' failed


问题是,如果将该方法中的第一个参数类型改为 void *htim的话,link就不出错,能正常生成.bin文件。
类似的问题已经遇到好几次了,一旦在自定义类的函数定义中使用到hal库的变量类型就会出现连接错误。但是使用普通的变量类型就完全OK。
是不是那里设置上遗漏了什么?


maxtch 发表于 2018-3-12 15:34:11

这个应该是 HAL 的暗病,头文件没做 C++ 兼容。试试看往 HAL 的头文件里面加上 __BEGIN_DECLS 和 __END_DECLS 能不能解决。

jjbboox 发表于 2018-3-12 17:29:15

maxtch 发表于 2018-3-12 15:34
这个应该是 HAL 的暗病,头文件没做 C++ 兼容。试试看往 HAL 的头文件里面加上 __BEGIN_DECLS 和 __END_DEC ...

看过头文件。
HAL的头文件中都有

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

__BEGIN_DECLS是一个意思吗?
编译的时候也没出错啊!

maxtch 发表于 2018-3-12 22:25:46

__BEGIN_DECLS

#ifdef __cplusplus
extern "C" {
#endif
是一回事。

jjbboox 发表于 2018-3-20 16:21:01

本帖最后由 jjbboox 于 2018-3-20 16:22 编辑

问题原因找到了

不是__cplusplus的问题。
之所以编译出错是HAL的头文件存在bug。

经过仔细调查,发现 TIM_HandleTypeDef是不会出错的,只有SPI_HandelTypeDef类型会出错。
跑到头文件中去查看,发现该类型结构的定义存在问题。定义代码如下:
/**
* @briefSPI handle Structure definition
*/
typedef struct __SPI_HandleTypeDef
{
SPI_TypeDef                *Instance;    /*!< SPI registers base address */

SPI_InitTypeDef            Init;         /*!< SPI communication parameters */

uint8_t                  *pTxBuffPtr;/*!< Pointer to SPI Tx transfer Buffer */

uint16_t                   TxXferSize;   /*!< SPI Tx Transfer size */

__IO uint16_t            TxXferCount;/*!< SPI Tx Transfer Counter */

uint8_t                  *pRxBuffPtr;/*!< Pointer to SPI Rx transfer Buffer */

uint16_t                   RxXferSize;   /*!< SPI Rx Transfer size */

__IO uint16_t            RxXferCount;/*!< SPI Rx Transfer Counter */

void                     (*RxISR)(struct __SPI_HandleTypeDef * hspi); /*!< function pointer on Rx ISR */

void                     (*TxISR)(struct __SPI_HandleTypeDef * hspi); /*!< function pointer on Tx ISR */

DMA_HandleTypeDef          *hdmatx;      /*!< SPI Tx DMA Handle parameters   */

DMA_HandleTypeDef          *hdmarx;      /*!< SPI Rx DMA Handle parameters   */

HAL_LockTypeDef            Lock;         /*!< Locking object               */

__IO HAL_SPI_StateTypeDefState;      /*!< SPI communication state */

__IO uint32_t            ErrorCode;    /*!< SPI Error code */

}SPI_HandleTypeDef;


通常我们在用typedef定义一个类型的时候 typedef struct后面是不带名称的,只会在结构体最后起名,
但是该类型定义却在typedef struct 后定义为 ,而在结构体定义最后又起名为,导致编译器无法将识别为一个有效的变量类型。

现在通过将参数类型更改为 struct __SPI_HandleTypeDef后问题解决。
该问题在编译器中貌似不会出问题,但是如果是C++编译器就会出错了。
可能是HAL库的bug。
页: [1]
查看完整版本: 求教:sw4stm32编译C++工程 Link的时候出错,请大神帮忙看看