起因
起因是笔者要移植一个Arduino库到STM32。这个库使用了C++的面向对象,转写为C工程量较大,故有此文。
环境
STM32CubeIDE v1.16.1
STM32CubeMX v6.12.1
实操
简析调用关系
现有一个后缀为.cpp
的陀螺仪驱动文件,涉及一些调用关系:
BNO08x_Driver.cpp
调用了I2C函数和UART函数,也有一些操作涉及中断。BNO08x_Driver.cpp
中的函数被main.c
调用。
所以上述所有涉及的.c
文件(i2c.c
、usart.c
、main.c
,如果你勾选了Generate peripheral initialization as a pair of '.c/.h' files per peripheral
则会有单独的i2c.c
和usart.c
)都需要改后缀为.cpp
。
转换为C++
没错,CubeIDE就是这么善解人意。按理说你点了这个,此文到此结束了就(但是还建议你继续往下看bushi)。
蛮聪明的确实,会自动选择编译器编译.c
和.cpp
。
诶?这是什么鬼!
什么都不报错,偏偏class
报错……而class
是C++的特性……
再往前一看,“In file included from”
,回想我们前文简析调用关系,原来是stm32l4xx_hal_msp.c
没有改写为.cpp
。修复后编译无误:
总结:至此已经可以使用C/C++混合编译,编译器已经正常工作。其他问题请修改代码(99%是语法问题)。
.c
与.cpp
互换*
这很重要。
什么时候需要修改后缀?答:使用CubeMX重新生成代码时,如果你不想CubeMX没法儿识别源文件,然后你的项目共存main.c
和main.cpp
的话。
附上一段Python(使用的时候需要修改路径,制定需要转换的文件列表):
import os
# 指定根目录,确保路径与实际文件路径一致
root_directory = "/Users/lff/GitHub/AI-MEMS/Embedded/AI-MEMS"
# 指定需要转换的文件相对路径列表(相对于 root_directory)
file_paths = [
"Core/Src/gpio.c", # 初始状态可以是 .c 或 .cpp
"Core/Src/i2c.c",
"Core/Src/main.c",
"Core/Src/stm32l4xx_hal_msp.c",
"Core/Src/stm32l4xx_it.c",
"Core/Src/usart.c"
]
# 标志位,用来确定文件当前是否是 .c
all_are_c = True
# 遍历指定文件路径检查是否所有文件都是 .c
for relative_path in file_paths:
# 获取文件的完整路径
file_path = os.path.join(root_directory, relative_path)
# 如果当前文件不是 .c 则标志位设置为 False
if not os.path.isfile(file_path):
all_are_c = False
break
# 根据当前状态决定目标扩展名
if all_are_c:
target_extension = ".cpp"
source_extension = ".c"
else:
target_extension = ".c"
source_extension = ".cpp"
# 执行文件名切换
for relative_path in file_paths:
# 获取文件的完整路径
file_path = os.path.join(root_directory, relative_path.replace(".c", source_extension).replace(".cpp", source_extension))
# 目标路径,切换扩展名
new_file_path = file_path[:-len(source_extension)] + target_extension
# 重命名文件
if os.path.isfile(file_path):
os.rename(file_path, new_file_path)
print(f"Renamed: {file_path} -> {new_file_path}")
else:
print(f"File not found or already renamed: {file_path}")
print(f"All files have been converted to {target_extension}.")
.py
文件的位置: