Undefined Reference error with a defined reference

I am currently implementing rosserial with an existing project but the linker is unable to find functions I defined for rosserial:
"undefined reference to start_ros_com'"*, *undefined reference to publish_position’

Including other self-written files like “MotorControl” and “GlobalVariables” workers without a problem and during compiling the compiler outputs “Compiling .pio\build\esp-wrover-kit\src\RosCom.cpp.o”, indicating that the file RosCom is included.

I tried hours of debugging, deleting .pio, restarting VSCode, restarting the PC and nothing changes the behaviour. ChatGPT and Phind are in a loop of are you sure that RosCom.h is in the correct folder and make sure the function is named correctly.

It’s my first time using FreeRTOS, is my fault maybe there?

├── platformio.ini
├── src
      └── main.cpp
      └── RosCom.cpp
      └── RosCom.h
      └── MotorControl.cpp
      └── MotorControl.h
      └── ui
            └── ui files for lvgl gui

RosCom.h gets imported in main.cpp like this:

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

and used like this:

void ROSSerialTask(void *pvParameters) {
    start_ros_com(); // Initialize ROS communication
    for (;;) {
        // Publish current positions
        publish_position();
        vTaskDelay(pdMS_TO_TICKS(5));
    }
}

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

  xTaskCreatePinnedToCore(ROSSerialTask, "ROSSerialTask", 2048, NULL, 1, NULL, 0);

 //other functions that worked before
}

void loop() {
  lv_timer_handler(); // GUI Task Handler
  delay(1);
  vTaskDelete(NULL);
}

RosCom.h is defined as the following:

#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

And RosCom.cpp like this:

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

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

bool ros_communication_working = false;

// Forward declaration of receive_position function
void receive_position(const std_msgs::Int32MultiArray& cmd_msg);

//ros node and publisher
std_msgs::Int32MultiArray actual_position_msg;

ros::Publisher pub_actualpos("actual_position", &actual_position_msg);
ros::Subscriber<std_msgs::Int32MultiArray> sub("wanted_position", receive_position);

ros::NodeHandle nh;

// Initialize ROS communication
void start_ros_com(){
    nh.initNode();
    nh.subscribe(sub);
    nh.advertise(pub_actualpos);
}

int wanted_position[2];

// Receiving wanted positions
void receive_position(const std_msgs::Int32MultiArray& cmd_msg){
    if (cmd_msg.data_length == 2) { // Assuming you're expecting a pair of positions
        wanted_position[0] = cmd_msg.data[0];
        wanted_position[1] = cmd_msg.data[1];
        move_motors();
    } else {
        Serial.println("Invalid data received for wanted positions.");
    }
}

// Publish current positions
void publish_position(){
    actual_position_msg.data_length = 2; // Assuming you're publishing a pair of positions
    actual_position_msg.data[0] = current_position[0];
    actual_position_msg.data[1] = current_position[1];
    pub_actualpos.publish(&actual_position_msg);
    nh.spinOnce();

    //ros_communication_working = nh.connected();
    if (ros_communication_working) {
        lv_obj_add_state(ui_roscomcheckbox, LV_STATE_CHECKED);
        Serial.println("ROSCOM Working");
    } else {
        lv_obj_clear_state(ui_roscomcheckbox, LV_STATE_CHECKED);
        Serial.println("ROSCOM NOT Working");
    }
}

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

Good morning Markus!

This does not mean that there is an #include <RosCom.h> somewhere in the code. It means that the source file RosCom.cpp was found and compiled by the compiler.

It is common for the corresponding .h file to be included in the .cpp file.
This means that the .cpp file has the required pre-declarations.

You should therefore add an #include "RosCom.h" to your RosCom.cpp.

This also makes the pre-declaration of the receive_position() function in the .cpp unnecessary.

As I understand it, the error lies in the fact that you declare your C++ functions as pure C functions. This means that the linker cannot find them.
(maxgerhard may forgive me for this simplified and perhaps incomplete explanation :wink: )

Solution: delete

#ifdef __cplusplus
extern "C" {
#endif

and

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

from your RosCom.h and the compilation should work.