C++项目集成btstack的C代码时出现函数未定义引用链接错误如何解决
btstack集成UDP服务端未定义引用问题解决方案
核心问题1:Makefile未编译btstack相关C源码
你定义的CORE变量中所有btstack的C源文件完全没有被加入编译流程,当前SRC仅匹配了./src/*.cpp,生成的目标文件集合中没有btstack函数的实现,自然会报未定义引用。
核心问题2:编译工具链与符号匹配问题
- 你直接用
g++编译C源文件会给C函数加上C++名字修饰,和你extern "C"声明的函数符号不匹配 - 你
CORE变量里包含了main.c,会和你C++代码中的main函数冲突 INCLUDE路径开头漏写/会导致引入Makefile.inc失败
具体修改方案
1. 修正Makefile规则
修改后的Makefile核心逻辑如下:
CORE += \ btstack_chipset_bcm.c \ btstack_chipset_bcm_download_firmware.c \ btstack_control_raspi.c \ btstack_link_key_db_tlv.c \ btstack_run_loop_posix.c \ btstack_tlv_posix.c \ btstack_uart_posix.c \ btstack_slip.c \ hci_dump_posix_fs.c \ hci_transport_h4.c \ hci_transport_h5.c \ le_device_db_tlv.c \ wav_util.c \ btstack_stdin_posix.c \ raspi_get_model.c \ rijndael.c # 删掉CORE里的main.c,避免和C++的main冲突 .INCLUDE : /home/pi/udpDemo/inc/btstack-master/example/Makefile.inc # 路径开头补/ CC = gcc CXX = g++ CFLAGS = -Wall -Wextra CXXFLAGS = -Wall -Wextra -pedantic -std=c++11 SRC=$(wildcard ./src/*.cpp) # 新增C文件对应的目标文件规则 C_OBJ = $(patsubst %.c, ./obj/%.o, $(CORE)) OBJ = $(patsubst ./src/%.cpp, ./obj/%.o, $(SRC)) $(C_OBJ) INC=-I./inc \ -I./inc/btsrc \ -I./inc/btsrc/ble \ -I./inc/btsrc/ble/gatt-service \ -I./inc/platform/embedded \ -I./inc/platform/posix \ -I./inc/chipset/bcm \ -I./inc/3rd-party/tinydir \ -I./inc/3rd-party/rijndael \ -I./inc/port/raspi \ -I./src LDFLAGS += -lrt VPATH += src VPATH += inc/3rd-party/rijndael VPATH += inc VPATH += inc/btsrc \ VPATH += inc/btsrc/ble \ VPATH += inc/btsrc/ble/gatt-service \ VPATH += inc/platform/embedded \ VPATH += inc/platform/posix \ VPATH += inc/chipset/bcm \ VPATH += inc/3rd-party/tinydir \ VPATH += inc/3rd-party/rijndael \ VPATH += inc/port/raspi \ LIBS= TARGET=test bindir=/usr/local/bin $(TARGET):$(OBJ) $(CXX) -o $@ $^ $(LDFLAGS) $(LIBS) # C++文件编译规则 ./obj/%.o:./src/%.cpp $(CXX) $(CXXFLAGS) -c $^ -o $@ $(INC) # 新增C文件编译规则,用gcc编译 ./obj/%.o: %.c mkdir -p obj $(CC) $(CFLAGS) -c $< -o $@ $(INC) clean: rm -rf $(TARGET) $(OBJ) ./obj install:$(TARGET) install -g root -o root $(TARGET) $(bindir)/$(TARGET) uninstall:$(bindir)/$(TARGET) rm $(bindir)/$(TARGET)
2. 确认extern "C"包裹正确性
所有btstack相关C头文件的引入必须全部放在extern "C"块内,示例写法:
extern "C" { #include "btstack.h" #include "l2cap.h" // 其余所有btstack的C头文件都放在此处 }
如果btstack头文件本身自带了C++兼容的extern "C"守卫,可以不用额外包裹,建议直接包裹所有引入的btstack头文件避免符号不匹配。
内容的提问来源于stack exchange,提问作者BuckTurgidson
相关产品推荐
相关产品推荐

