Search code examples
c++vectorfunction-pointersevent-driven-design

calling function pointer of a member function from a function pointer vector


i think this is mostly a syntax error ( though not captured during compilation, only at runtime does the error happen)

i am trying to develop an event driven architecture , where i keep a vector of eventReceiver and try to call them from the vector.

CommonIO.h

    class CommonIO {
    public:
        typedef void (*incomingMsgReceiver)(char*);
            void registerForIncomingMsg(incomingMsgReceiver);
            void incomingMsgReceived(char*);
    }

CommonIO.cpp

    std::vector<void (*)(char*)> listeners;

    void CommonIO::registerForIncomingMsg(incomingMsgReceiver receiverFunction) {
        listeners.push_back(receiverFunction);
    }

    void CommonIO::incomingMsgReceived(char* buf) {
        for (unsigned int j = 0; j < listeners.size(); j++) {
                listeners[i](buf);  //error, segmentation fault..how do i call it?
            }
    }

Main.h

class Main {
public:
     static void msgReceived(char*);
     void mainLoop();

}

Main.cpp

void Main::msgReceived(char* msg)
{
    printf("\n\n --------->>>>> %s \n\n" , msg);
}

void Main::mainLoop()
{
     CommonIO::incomingMsgReceiver receiver = &Main::msgReceived;
     CommonIO::getInstance()->registerForIncomingMsg( receiver );
}

incomingMsgReceived function is called by an asynchronous process

the program compiles fine..however breaks down at : listenersi; line. what is the proper syntax for this ?


Solution

  • Why not use inheritance and a common base class? Makes simpler code and also you are detailing with objects so you have data, other methods etc.

    i.e. something like this

    class incomingMsgReceiver {
       public:
          virtual void msgReceived(char *msg) = 0;
    };
    
    class MyMessage : public incomingMsgReceiver {
       public virual void msgReceieved(char *msg);
    }
    
    class OtherMyMessage : public incomingMsgReceiver {
       public virual void msgReceieved(char *msg);
    }
    
    void MyMessage::msgReceived(char *msg)
    {
       /// Do stuff here
    
    }
    
    void msgReceived::OtherMyMessage(char *msg)
    {
       /// Do stuff here
    
    }
    

    Then for your common.h:

    class CommonIO
    {
       private:
          std::vector<incomingMsgReceiver *> listeners;
       public:
          void addListner(incomingMsgReceiver *reveiver) { listners.push_back(reveiver); }
    
          void incomingMsgReceived(char*msg)
          {
             for (unsigned int j = 0; j < listeners.size(); j++)
             {
                listeners[j]->msgReceived((msg);
             }
          }
    };