树莓派4B上C++编译DJI Payload SDK链接错误修复咨询
问题描述
在Raspberry Pi 4B上使用C++编译DJI Payload SDK时出现大量未定义引用错误,但C语言编译可正常完成。相关信息如下:
项目环境与结构
项目目录结构:
manifold2 | |--application/ |--build/ |--hal/ |--CMakeLists.txt
编译执行步骤:
cd build cmake .. make
已做操作
已在C语言头文件中用extern "C"包裹UART相关函数声明:
#ifdef __cplusplus extern "C" { #endif /* Exported constants --------------------------------------------------------*/ // 用户可根据环境配置设备 #define LINUX_UART_DEV1 "/dev/ttyS0" #define LINUX_UART_DEV2 "/dev/ttyACM0" /* Exported types ------------------------------------------------------------*/ /* Exported functions --------------------------------------------------------*/ T_DjiReturnCode HalUart_Init(E_DjiHalUartNum uartNum, uint32_t baudRate, T_DjiUartHandle *uartHandle); T_DjiReturnCode HalUart_DeInit(T_DjiUartHandle uartHandle); T_DjiReturnCode HalUart_WriteData(T_DjiUartHandle uartHandle, const uint8_t *buf, uint32_t len, uint32_t *realLen); T_DjiReturnCode HalUart_ReadData(T_DjiUartHandle uartHandle, uint8_t *buf, uint32_t len, uint32_t *realLen); T_DjiReturnCode HalUart_GetStatus(E_DjiHalUartNum uartNum, T_DjiUartStatus *status); #ifdef __cplusplus } #endif
编译错误信息(关键片段)
-- - Libraries: /usr/lib/aarch64-linux-gnu/libavcodec.so;/usr/lib/aarch64-linux-gnu/libavformat.so;/usr/lib/aarch64-linux-gnu/libavutil.so;/usr/lib/aarch64-linux-gnu/libswscale.so;/usr/lib/aarch64-linux-gnu/libz.so -- - Version: 4.3.5-0+deb11u1+rpt3 -- Cannot Find OPUS -- Cannot Find LIBUSB -- Configuring done -- Generating done -- Build files have been written to: /home/danny/Desktop/payload_master/Payload-SDK/samples/sample_c++/platform/linux/manifold2/build /usr/bin/ld: CMakeFiles/dji_sdk_demo_linux_cxx.dir/application/application.cpp.o: in function `Application::Application(int, char**)': application.cpp:(.text+0x5c): undefined reference to `Osal_TaskSleepMs' /usr/bin/ld: CMakeFiles/dji_sdk_demo_linux_cxx.dir/application/application.cpp.o: in function `Application::DjiUser_SetupEnvironment()': application.cpp:(.text+0xcc): undefined reference to `HalNetWork_Init' /usr/bin/ld: application.cpp:(.text+0xd0): undefined reference to `HalNetWork_Init' /usr/bin/ld: application.cpp:(.text+0xd8): undefined reference to `HalNetWork_DeInit' /usr/bin/ld: application.cpp:(.text+0xdc): undefined reference to `HalNetWork_DeInit' /usr/bin/ld: application.cpp:(.text+0xe4): undefined reference to `HalNetWork_GetDeviceInfo' /usr/bin/ld: application.cpp:(.text+0xe8): undefined reference to `HalNetWork_GetDeviceInfo' /usr/bin/ld: application.cpp:(.text+0xf0): undefined reference to `Osal_Socket' /usr/bin/ld: application.cpp:(.text+0xf4): undefined reference to `Osal_Socket' /usr/bin/ld: application.cpp:(.text+0xfc): undefined reference to `Osal_Bind' /usr/bin/ld: application.cpp:(.text+0x100): undefined reference to `Osal_Bind' /usr/bin/ld: application.cpp:(.text+0x108): undefined reference to `Osal_Close' /usr/bin/ld: application.cpp:(.text+0x10c): undefined reference to `Osal_Close' /usr/bin/ld: application.cpp:(.text+0x114): undefined reference to `Osal_UdpSendData' /usr/bin/ld: application.cpp:(.text+0x118): undefined reference to `Osal_UdpSendData' /usr/bin/ld: application.cpp:(.text+0x120): undefined reference to `Osal_UdpRecvData'
解决方案
这些错误的核心是C++编译器对C函数名进行了名称修饰(Name Mangling),你仅给UART相关函数添加了extern "C",但错误中涉及的Osal_*、HalNetWork_*等函数未被正确声明为C链接。
1. 补全所有C头文件的extern "C"包裹
确保所有被C代码调用的C语言头文件(包括OSAL、网络相关头文件)都用extern "C"包裹函数声明。如果是SDK自带的头文件,无法直接修改的话,可在C代码中包含时手动包裹:
extern "C" { #include "osal.h" #include "hal_network.h" // 其他需要调用的C头文件 }
2. 修改CMakeLists.txt确保C代码按C规则编译
在CMakeLists.txt中明确标记C源文件的编译语言,避免被当作C++编译:
- 针对单个C库:
add_library(hal_network STATIC hal/network/hal_network.c) set_target_properties(hal_network PROPERTIES LINKER_LANGUAGE C) add_library(osal STATIC osal/osal.c) set_target_properties(osal PROPERTIES LINKER_LANGUAGE C)
- 批量处理C源文件:
file(GLOB C_SOURCES "hal/*.c" "osal/*.c") set_source_files_properties(${C_SOURCES} PROPERTIES LANGUAGE C)
3. 确认链接依赖顺序
在CMakeLists.txt中,确保C++目标正确链接所有需要的C语言库,且依赖库放在使用它的目标之后:
target_link_libraries(dji_sdk_demo_linux_cxx hal_uart hal_network osal # 其他SDK依赖库 )
4. 清理重建
修改完成后,清理旧构建文件重新编译:
cd build rm -rf * cmake .. make
内容的提问来源于stack exchange,提问作者許子霆
相关产品推荐
相关产品推荐

