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

PlatformIO中已定义函数出现Undefined Reference错误求助

问题:Rosserial集成时链接器找不到已定义的函数

错误现象

在ESP32项目中集成rosserial时,链接器抛出以下错误:

undefined reference to `start_ros_com'
undefined reference to `publish_position'

其他自定义模块(如MotorControl、GlobalVariables)可正常引用,编译日志显示.pio\build\esp-wrover-kit\src\RosCom.cpp.o已被编译,但链接阶段仍找不到目标函数。已尝试删除.pio目录、重启VSCode/电脑,问题依旧。首次使用FreeRTOS,怀疑是否与此相关。

项目环境与代码

目录结构

├── platformio.ini
├── src
      ├── main.cpp
      ├── RosCom.cpp
      ├── RosCom.h
      ├── MotorControl.cpp
      ├── MotorControl.h
      └── ui
            └── lvgl相关UI文件

main.cpp关键代码

#include "MotorControl.h"
#include "ui/ui.h"
#include "RosCom.h"

void ROSSerialTask(void *pvParameters) {
    start_ros_com(); // 初始化ROS通信
    for (;;) {
        publish_position(); // 发布当前位置
        vTaskDelay(pdMS_TO_TICKS(5));
    }
}

void setup() {
  Serial.begin(115200);
  delay(1000);

  xTaskCreatePinnedToCore(ROSSerialTask, "ROSSerialTask", 2048, NULL, 1, NULL, 0);
  // 其他正常工作的初始化代码
}

void loop() {
  lv_timer_handler(); // GUI任务处理
  delay(1);
  vTaskDelete(NULL);
}

RosCom.h定义

#ifndef ROSCOM_H
#define ROSCOM_H

#include <std_msgs/Int32MultiArray.h>

#ifdef __cplusplus
extern "C" {
#endif

void start_ros_com();
void receive_position(const std_msgs::Int32MultiArray& cmd_msg);
void publish_position();

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif // ROSCOM_H

RosCom.cpp实现(关键部分)

#include <ros.h>
#include <std_msgs/Int32MultiArray.h>

#include "MotorControl.h"
#include "ui/ui.h"
#include <lvgl.h>
#include "GlobalVariables.h"

ros::NodeHandle nh;

void start_ros_com(){
    nh.initNode();
    nh.subscribe(sub);
    nh.advertise(pub_actualpos);
}

void publish_position(){
    actual_position_msg.data_length = 2;
    actual_position_msg.data[0] = current_position[0];
    actual_position_msg.data[1] = current_position[1];
    pub_actualpos.publish(&actual_position_msg);
    nh.spinOnce();
    // 其他UI状态更新代码
}

platformio.ini配置

[env:esp-wrover-kit]
platform = espressif32
board = esp-wrover-kit
framework = arduino
monitor_port = /dev/ttyUSB*
monitor_speed = 115200
lib_deps = 
    teemuatlut/TMCStepper@^0.7.3
    gin66/FastAccelStepper@^0.28.3
    lovyan03/LovyanGFX@^0.4.14
    lvgl/lvgl@^8.3.6
    frankjoshua/Rosserial Arduino Library@^0.9.1
    khoek/libesp @ ^2.3.0

upload_speed = 921600
build_flags = 
    -DBOARD_HAS_PSRAM
    -mfix-esp32-psram-cache-issue
    -DLV_CONF_INCLUDE_SIMPLE
    -D LV_COMP_CONF_INCLUDE_SIMPLE
    -I src/
    -I src/ui

问题原因

核心问题是**extern "C"的错误使用**:

  1. 在extern "C"块中声明了带C类型参数的函数receive_position(const std_msgs::Int32MultiArray& cmd_msg),但C语言不支持C的引用类型和命名空间,导致编译器处理函数名修饰时出现混乱。
  2. Arduino框架基于C++,整个项目的编译环境都是C++,不需要额外添加extern "C"兼容C代码,反而会破坏C++的函数名修饰规则,导致链接器找不到正确的函数符号。
  3. FreeRTOS不是问题根源,你在FreeRTOS任务中调用函数的方式没有错误。

解决方案

修改RosCom.h,移除不必要的extern "C"块:

#ifndef ROSCOM_H
#define ROSCOM_H

#include <std_msgs/Int32MultiArray.h>

// 直接声明C++函数,无需extern "C"
void start_ros_com();
void receive_position(const std_msgs::Int32MultiArray& cmd_msg);
void publish_position();

#endif // ROSCOM_H

修改后重新编译项目,链接器错误即可解决。

内容的提问来源于stack exchange,提问作者genericname

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 20:39:52