You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派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,提问作者許子霆

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 20:17:06