I have a class, called Channel_thread
. As you can guess, one of its function is threaded, and in this function I would like to call another member function, depending on situations. That's why I used an array of member functions.
Here is how the code looks like :
Channel_thread.cpp :
#include <boost/bind.hpp>
#include "../include/Channel_thread.h"
Channel_thread::Channel_thread(Event_queue<std::deque<char>> *_serverQueue, Event_queue<std::deque<char>> *_messageQueue)
{
serverQueue = _serverQueue;
messageQueue = _messageQueue;
}
void Channel_thread::startThread()
{
isRunning = true;
t = new boost::thread(boost::bind(&Channel_thread::start, this));
}
void Channel_thread::start(void *data)
{
auto *_this = (Channel_thread *)data;
Message *messageReceived = NULL;
while (_this->isRunning)
{
std::pair<std::string, std::deque<char>> p(_this->messageQueue->wait_and_pop());
for (int index = 0; index != 4; index++)
{
if (_this->handlersIndexTab[index] == p.first)
{
messageReceived = _this->handlersTab[index](p.second);
break ;
}
}
}
}
Message *Channel_thread::channelSetupHandler(std::deque<char> bytes)
{
//Do stuff
}
Message *Channel_thread::channelStatusHandler(std::deque<char> bytes)
{
//Do stuff
}
Message *Channel_thread::channelCloseHandler(std::deque<char> bytes)
{
//Do stuff
}
Message *Channel_thread::streamSetupHandler(std::deque<char> bytes)
{
//Do stuff
}
Channel_thread.h
#include <boost/thread.hpp>
#include "Event_queue.h"
#include "Channel_setup.h"
#include "Channel_status.h"
#include "Channel_close.h"
#include "Stream_setup.h"
class Channel_thread {
typedef Message *(Channel_thread::*fn)(std::deque<char>);
public:
Channel_thread(Event_queue<std::deque<char>> *, Event_queue<std::deque<char>> *);
static void start(void *);
void startThread();
Message *channelSetupHandler(std::deque<char>);
Message *channelStatusHandler(std::deque<char>);
Message *channelCloseHandler(std::deque<char>);
Message *streamSetupHandler(std::deque<char>);
private:
Event_queue<std::deque<char>> *messageQueue;
Event_queue<std::deque<char>> *serverQueue;
bool isRunning;
boost::thread *t;
fn handlersTab[4] = {channelSetupHandler, channelStatusHandler, channelCloseHandler, streamSetupHandler};
std::string handlersIndexTab[4] = {"channel_setup", "channel_status", "channel_close", "stream_setup"};
};
I get this error :
/cygdrive/c/Users/foo/CLionProjects/Server_cpp/src/Channel_thread.cpp: In static member function 'static void Channel_thread::start(void*)':
/cygdrive/c/Users/foo/CLionProjects/Server_cpp/src/Channel_thread.cpp:35:69: error: must use '.*' or '->*' to call pointer-to-member function in '_this->Channel_thread::handlersTab[index] (...)', e.g. '(... ->* _this->Channel_thread::handlersTab[index]) (...)'
messageReceived = _this->handlersTab[index](p.second);
As you can see, the way I call a member function in my array seems to be wrong, maybe because of the static
context, I don't really know, and so my question is :
How to call member functions stored in an member functions array from a static function?
Thanks in advance.
There are couple of problems with using _this->handlersTab[index](p.second);
.
The syntax for using a member function pointer is different than using a member function. A member function pointer needs to be dereferenced before getting called. Give a member function pointer, mfPtr
, the syntax to use is (objectPtr->*mfPtr)(...)
. See the section Pointers to member functions at https://en.cppreference.com/w/cpp/language/pointer for further details.
The second problem is that handlersTab
is not a static
member variable. To get a pointer to the member function, you have to use _this->handlersTab
.
A one liner to make the function call would be:
messageReceived = (_this->*(_this->handlersTab[index]))(p.second);
I would suggest simplifying it by using two lines.
fn handler = _this->handlersTab[index];
messageReceived = (_this->*handler)(p.second);