karl71 karl71 - 1 month ago 21
C++ Question

Pass ZMQ context to thread

In C++ I'm using ZeroMQ to build a simple client-server chatting application. Once the context is initialised in the main, I'd like to pass it to a thread and declare there the socket used to output the messages of the user (i.e. to perform the send). This is my current code (client/user side):

void Send(zmq::context_t& c ) // To get messages from user and send them to the server
{
zmq::socket_t socket(c, ZMQ_REQ);
socket.connect ("tcp://192.168.1.84:5555");

std::string mssg;

while (true) {

std::getline(std::cin, mssg);

if(mssg == "#exit")
{
killApp = true; // an atomic<bool> used to terminate all threads
break;
}
zmq::message_t mssg_(mssg.length());
std::memcpy(mssg_.data(), mssg.data(), mssg.length());

socket.send(mssg_);

}

}

int main ()
{
// Initialising the context
std::shared_ptr<zmq::context_t> context = std::make_shared<zmq::context_t>(1);
std::thread t_send(Send, *context.get()); // THIS DOESN'T WORK

{
// do some stuff in the main thread (e.g. display the messages)
}

t_send.join();
return 0;
}


I'm trying to pass the context by reference to the thread so I can create a socket and perform the rest of the operation. But I don't know how to do it properly. (alternatively, passing a zmq::socket_t is also fine, but I'm facing the same issue trying to do that).

Answer

Here is how I've solved it: Passing the context as a void pointer and then casting it back to zmq::context_t:

void Send(void* context ) // To get messages from user and send them to the server
{ 
    zmq::socket_t s(*(zmq::context_t*)context,ZMQ_REQ);
    s.connect ("tcp://192.168.1.84:5555");
    ...
    ...
}

int main()
{
    std::shared_ptr<zmq::context_t> context = std::make_shared<zmq::context_t>(1);
    std::thread t_send(Send, static_cast<void*>(context.get()));
    ...
    return 0;
}

Hope it helps someone in the future.