Boost.Interprocess: How to call and send data to a function from class that is in another process?

1.7k Views Asked by At

So I have created a simple class that works for threads - you can add any void function of any class to a list of subscribed functions of a class that enherits from presented my class:

#include <iostream>
#include <vector>

#include <boost/thread.hpp>

// parts of c++0x std
#include <boost/bind.hpp> 
#include <boost/function.hpp>

#ifndef _CoreEvents_h_
#define _CoreEvents_h_

using namespace std ;
template <typename DataType >
class CoreEvents{

        typedef boost::function<void(DataType)>   Function;
        typedef std::vector<Function>      FunctionSequence;
        typedef typename FunctionSequence::iterator FunctionIterator; 

public:
        DataType* dataElement;
        FunctionSequence funcs;
        boost::thread_group tg;

        CoreEvents()
        {
                dataElement = new DataType();
        }
        // Function for adding subscribers functions
        // use something like std::bind(&currentClassName::FunctionToAdd, this, std::placeholders::_1) to add function to vector
        void Add(Function f)
        {
                funcs.push_back(f);
        }

        // Cast data to subscribers and clean up given pointer
        //ToDo: One  will be solved when pool of pre-initialized objects will be developed 
        virtual void Cast(){
                for (FunctionIterator it(funcs.begin()); it != funcs.end(); ++it){
                        DataType dataCopy = *dataElement;
                        tg.create_thread(boost::bind(*it, dataCopy));
                }
        }  
};

All you need to subscribe is:

someClass->Add(boost::bind(&someOtherClass::someVoidFunction, this, _1)); 

This is simple when we deal with threads - we can always call for example create_thread and have all we need done in other app thread.

But what if we have app1 app2 and app3 and you want to share a pointer of a function form one process and using broker app give that pointer to another app so that it could be called with parameters from last process/app?

In real life it would look like if we had an app with not editable text feild running, and an app with editable text field running. and we had app №3 that could connect input from editable TF to not editable TF.

Is it possible with Boost.Interprocess and how to do such thing?

I am quite new to C++ but I think I found some bad info related:

References forbidden

References suffer from the same problem as pointers (mainly because they are implemented as pointers). However, it is not possible to create a fully workable smart reference currently in C++ (for example, operator .() can't be overloaded). Because of this, if the user wants to put an object in shared memory, the object can't have any (smart or not) reference as a member.

References will only work if the mapped region is mapped in the same base address in all processes sharing a memory segment. Like pointers, a reference placed in a mapped region should only point to an object of that mapped region.

Virtuality forbidden

The virtual table pointer and the virtual table are in the address space of the process that constructs the object, so if we place a class with a virtual function or virtual base class, the virtual pointer placed in shared memory will be invalid for other processes and they will crash.

This problem is very difficult to solve, since each process needs a different virtual table pointer and the object that contains that pointer is shared across many processes. Even if we map the mapped region in the same address in every process, the virtual table can be in a different address in every process. To enable virtual functions for objects shared between processes, deep compiler changes are needed and virtual functions would suffer a performance hit. That's why Boost.Interprocess does not have any plan to support virtual function and virtual inheritance in mapped regions shared between processes.

Be careful with static class members

Static members of classes are global objects shared by all instances of the class. Because of this, static members are implemented as global variables in processes.

When constructing a class with static members, each process has its own copy of the static member, so updating a static member in one process does not change the value of the static member the another process. So be careful with these classes. Static members are not dangerous if they are just constant variables initialized when the process starts, but they don't change at all (for example, when used like enums) and their value is the same for all.

But I am creating all my apps using one same library. and when I need best performance I will use threading, but it happens that I need an interprocess communication. So what shall I do - how to create a mechanism to emulate much needed functionality?

1

There are 1 best solutions below

1
On

Sorry, this question is a bit hard to understand, but I'll try to answer.

Sharing function pointers between processes is something you should almost never do. It's very dangerous. Sharing non-primitive data is also frowned upon, but okay in some cases.

Generally, you should use something like messaging for this. You may want to use Boost.Interprocess to share parameters.