Skip to content

Simple C++ Communication Manager using Shared Memory

Notifications You must be signed in to change notification settings

RicardoRagel/comms_manager

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

comms-manager

A simple C++ Inter-Process Communication (IPC) Manager using Shared Memory for Linux.

Overview

Although there are already several good IPC libraries integrated in different frameworks (ROS, Google Protobuf, Microsoft IPC, ...), The idea of this repository is to provide a simple, easy and framework-independent way to communicate two processes using shared memory.

This package provides:

  1. A really simple library class CommsManager to create your channel messages, publisher and subscribers.
  2. A logger program to save the current data of the channels that you select in binary data files.
  3. A player program to reproduce the previous saved binary data files.

Dependencies

This library is provided with a CMakeLists compiler file, so if you are going install it from source you need:

Installation

Debian package

This library and its tools can be installed using directly the provided debian file (check Releases page). We recommend install it using the APT command:

sudo apt install ./comms_manager-<version>-Linux.deb

Then if you need to remove it later, you can do it easily using the command: sudo apt remove comms_manager.

In case you are not able to use APT, use dpkg instead:

sudo dpkg -i comms_manager-<version>-Linux.deb

Once you have installed it, continue to the Usage and Examples sections.

From Source

Compile the CommsManager library and tools as usual:

mkdir build && cd build
cmake ..
make

And install it:

sudo make install

The default installation path of the library is: /usr/local/lib.

Usage

An example about how to link and use this library is provided in the example folder.

Linking this library from your project

Simply, add this lines to your CMakeLists.txt:

# Link for the shared library:
set(PROJECT_LINK_LIBS libCommsManager.so)
link_directories( ${CMAKE_INSTALL_PREFIX} ) # That is /usr/local

# Create executables
add_executable(your_app your_app.cpp)
target_link_libraries(your_app ${PROJECT_LINK_LIBS} )

Defining your messages

First, you need to define the message data as a struct:

struct ExampleData
{
	struct  timespec timestamp; // Real Time
	int 	i;                  // Example integer data 
};

Check the exmaple: example_data.h.

Then, you can create the message as a CommsManager child class that contains the previous data:

#include "CommsManager.hpp"
#include "example_data.h"

class ExampleMsg : public CommsManager 
{
  public:

	ExampleMsg(const char *channel_name) : CommsManager(channel_name, &data, sizeof(ExampleData))
	{
		// Initial time
		clock_gettime(CLOCK_REALTIME, &data.timestamp);

		// Default values
		i = -1;
	}
																	
    ExampleData data;
};

Check example message example_msg.h.

Creating a publisher

To publish the previous messages into a comms channel:

// Example Data Message
#include "msg/example_msg.h"

...

// Create the channel
ExampleMsg msg("/channel_name");

// Fill the message
clock_gettime(CLOCK_REALTIME, &msg.data.timestamp);
msg.data.i = 33;

// Pusblish it
msg.write();

Check the complete example in example_pub.cpp.

Creating a subscriber

To subscribe to the previous publisher channel and read the messages, there are two options: blocking or non-blocking readings:

// Example Data Message
#include "msg/example_msg.h"

...

// Create the channel
ExampleMsg msg("/channel_name");

// Read message from the channel
bool blocking = <true or false>;
bool new_msg_exist = msg.read(blocking);

if(new_msg_exist)
{
    printf("New message: i= %d\n", msg.data.i);

    <do something>
}
else
{
    printf("No new messages...\n");
}

Check the complete example in example_sub.cpp.

Logging channels

To save the data through one or several channels, you can easily do it using the installed comms_logger tool:

comms_logger /channel_name_1 /channel_name_2 ...

This will save the data in .log binary file called as the channel_name (plus the timestamp) inside a hidden folder, called .comms_log_files, at your home folder.

Playing back the saved channels and data

To play these previous log files, this package also provides the comms_player tool. Execute it together the name (without extension) of the log files you wish to reproduce:

comms_player _channel_name_1_log_file _channel_name_2_log_file ...

Examples

To test the provided examples, first go to the example folder and compile them:

cd example
mkdir build && cd build
cmake ..
make

Running the examples:

Once you have compiled and installed the library and compiled the example, just run the publisher example in one terminal:

./example_pub

and the subrscriber example in another terminal choosing the blocking option:

./example_sub true