在 C 项目中使用 C++ 代码的解决方案:
在嵌入式开发或其他需要同时使用 C 和 C++ 代码的项目中,C 代码需要通过合适的方式调用 C++ 类或函数。由于 C 和 C++ 的编译器和链接方式有所不同,C 和 C++ 的代码需要通过合适的方式交互(以stm32-make为例)。
1. 创建 C 代码中调用 C++ 类的接口文件Inint_Process.h
在 C 代码中,不能直接使用 C++ 的类实例化和成员函数调用,而是应该使用 C++ 提供的 C 风格接口来调用 C++ 类。
Inint_Process.h
(C 语言接口)
使用 extern "C"
来确保 C++ 编译器将这些接口函数按 C 语言的方式处理,避免 C++ 名称修饰问题。
/*
* Inint_Process.h
*
* Created on: Oct 4, 2024
* Author: T.Grove
* 注:此文件包含初始化及过程运行函数
*/
#ifndef INC_ININT_PROCESS_H_
#define INC_ININT_PROCESS_H_
#include "main.h"
#include "xxx.h"//C语言的头文件
#ifdef __cplusplus
extern "C"
{
#endif
void Use_Init();
void While_Process();
#ifdef __cplusplus
}
#endif
#endif /* INC_ININT_PROCESS_H_ */
2. 创建需要被main.c
直接调用的Inint_Process.cpp
/*
* Inint_Process.cpp
*
* Created on: Oct 4, 2024
* Author: T.Grove
* 注:此文件包含初始化及过程运行函数
*/
#include "Inint_Process.h"
#include "xxx.hpp"//C++的头文件
///*定时器中断回调函数*/
//void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
//{
//}
/*使用初始化*/
void Use_Init()
{
}
/*while里调用函数*/
void While_Process()
{
}
3. 在main.c
中调用Inint_Process.cpp
中的函数
......
#include "Inint_Process.h"
......
int main()
{
...
Use_Init();
while(1)
{
While_Process();
}
}
4. Makefile配置
4.1 添加 C++ 源文件(1处,复制后去除空行)
######################################
# source
######################################
#-----------------------------自行添加--------------------------------#
# C++ sources
CPP_SOURCES = \
Core/Src/Inint_Process.cpp \
#-----------------------------自行添加--------------------------------#
4.2 添加 C++ 编译链(2处)
#######################################
# binaries
#######################################
PREFIX = arm-none-eabi-
# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx)
# either it can be added to the PATH environment variable.
ifdef GCC_PATH
CC = $(GCC_PATH)/$(PREFIX)gcc
AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp
CP = $(GCC_PATH)/$(PREFIX)objcopy
SZ = $(GCC_PATH)/$(PREFIX)size
CPP = $(GCC_PATH)/$(PREFIX)g++ #<--------------------自行添加
else
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc -x assembler-with-cpp
CP = $(PREFIX)objcopy
SZ = $(PREFIX)size
CPP = $(PREFIX)g++ #<---------------------自行添加
endif
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S
4.3 配置 C++ 编译选项(1处)
# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
CPP_FLAGS = $(CFLAGS) -fno-rtti -fno-exceptions #<---------------------自行添加
4.4 添加 C++ 标准库(1处)
#######################################
# LDFLAGS
#######################################
# link script
LDSCRIPT = stm32f103zetx_flash.ld
# libraries
LIBS = -lc -lm -lnosys -u _printf_float -lstdc++ #<---------------------自行添加
4.5 添加 C++ 构建(3处)
#######################################
# build the application
#######################################
JSWYLL_EXTRA_COMPILE_DIRS := my_device_C my_device_C/ICM45686 my_device_C++ user
C_SOURCES += $(foreach dir, $(JSWYLL_EXTRA_COMPILE_DIRS), $(wildcard $(dir)/*.c))
C_INCLUDES += $(foreach dir, $(JSWYLL_EXTRA_COMPILE_DIRS), -I$(dir))
CPP_SOURCES += $(foreach dir, $(JSWYLL_EXTRA_COMPILE_DIRS), $(wildcard $(dir)/*.cpp))#<--------自行添加
ASM_SOURCES += $(foreach dir, $(JSWYLL_EXTRA_COMPILE_DIRS), $(wildcard $(dir)/*.s))
ASMM_SOURCES += $(foreach dir, $(JSWYLL_EXTRA_COMPILE_DIRS), $(wildcard $(dir)/*.S))
# list of objects
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))
#-----------------------------自行添加--------------------------------#
# list of C++ objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(CPP_SOURCES:.cpp=.o)))
vpath %.cpp $(sort $(dir $(CPP_SOURCES)))
#-----------------------------自行添加--------------------------------#
# list of ASM program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
vpath %.s $(sort $(dir $(ASM_SOURCES)))
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASMM_SOURCES:.S=.o)))
vpath %.S $(sort $(dir $(ASMM_SOURCES)))
$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
@echo compiling $<...
@$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
#-----------------------------自行添加--------------------------------#
$(BUILD_DIR)/%.o: %.cpp Makefile | $(BUILD_DIR)
@echo compiling $<...
@$(CPP) -c $(CPP_FLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.cpp=.lst)) $< -o $@
#-----------------------------自行添加--------------------------------#
$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
@echo compiling $<...
@$(AS) -c $(CFLAGS) $< -o $@
$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR)
@echo compiling $<...
@$(AS) -c $(CFLAGS) $< -o $@
$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
@echo linking...
@$(CC) $(OBJECTS) $(LDFLAGS) -o $@
@$(SZ) $@
$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
@$(HEX) $< $@
$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
@$(BIN) $< $@
$(BUILD_DIR):
@mkdir $@