Robotics StackExchange | Archived questions

Read topics from C | C++ Listener

Hello, Hope you are well!

I’m about to do a simple C program that reads from a simple ROS1 Publisher. The main problem is that I can’t figure out why I can’t read the value from C shared variable between C++ program.

I have a C program from which I want to read the values received by a topic. So, I want to extend the actual program capabilities reading from a C++ (ROS) variable, to do actions.

I tried to use Linux sockets, but seems to be slow for the task. Same with FIFO (Very SLOW)… For that reason I was thinking to read the value directly from a shared variable using a .so file… ( Probably you have another ideas? :) )

publisher.cpp

#include "ros/ros.h"
#include "std_msgs/String.h"
#include "shared_ros_variable.h"

char* ros_value;

void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
  ROS_INFO("I heard: [%s]", msg->data.c_str());
  ros_value = const_cast<char*>(msg->data.c_str());
  //ROS_INFO("I heard: [%s]", ros_value);
}
// %EndTag(CALLBACK)%

int main(int argc, char **argv)
{
  ros::init(argc, argv, "listener");
  ros::NodeHandle n;

// %Tag(SUBSCRIBER)%
  ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
// %EndTag(SUBSCRIBER)%

// %Tag(SPIN)%
  ros::spin();
// %EndTag(SPIN)%

  return 0;
}
// %EndTag(FULLTEXT)%

sharedrosvariable.h

#ifndef SHARED_ROS_VARIABLE_H
#define SHARED_ROS_VARIABLE_H

#ifdef __cplusplus
extern "C" {
#endif

extern char* ros_value; // declaration of the variable from halcmd_main.c

#ifdef __cplusplus
}
#endif

#endif // SHARED_ROS_VARIABLE

val_reader.c

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include "shared_ros_variable.h"

char* ros_value;

int main() {
    // Load the shared library
    void* handle = dlopen("build/liblistener_lib.so", RTLD_LAZY);
    if (!handle) {
        printf("Failed to load shared library: %s\n", dlerror());
        exit(1);
    }

    // Get a pointer to the char variable
    char* my_char_ptr = dlsym(handle, "ros_value");
    if (!my_char_ptr) {
        printf("Failed to get symbol: %s\n", dlerror());
        dlclose(handle);
        exit(1);
    }

    // Print the value of the char variable
    printf("Value of my_char_variable: %c\n", *my_char_ptr);

    // Close the shared library
    dlclose(handle);
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8.3)
project(myproject)

# Find the required ROS packages
find_package(roscpp REQUIRED)
find_package(std_msgs REQUIRED)

# Add the include directories for the ROS packages
include_directories(${roscpp_INCLUDE_DIRS})
include_directories(${std_msgs_INCLUDE_DIRS})

# Build the talker executable
add_executable(talker talker.cpp)
target_link_libraries(talker ${roscpp_LIBRARIES} ${std_msgs_LIBRARIES})

# Build the listener executable
add_executable(listener listener.cpp)
target_link_libraries(listener ${roscpp_LIBRARIES} ${std_msgs_LIBRARIES})


# Build the listener library
add_library(listener_lib SHARED listener.cpp)
set_target_properties(listener_lib PROPERTIES
        CXX_STANDARD 11
        CXX_STANDARD_REQUIRED YES
        CXX_EXTENSIONS NO
        POSITION_INDEPENDENT_CODE ON
        )
target_link_libraries(listener_lib ${roscpp_LIBRARIES} ${std_msgs_LIBRARIES})

# Install the executables and the library
install(TARGETS talker listener_lib
        DESTINATION bin)

The .C program is compiled independently, which reads the variable from .so file.

One thing that “worked”:

It takes the variable value if I ADD by hand the variable value in the .CPP file. But of course, the variable never changes.

Thanks and regards!

Asked by jjrbfi on 2023-03-18 02:58:11 UTC

Comments

Answers