feng
feng

Reputation: 25

How to pass zmq context (void *) properly?

I am using zmq's native C library to write my application (the application itself is written in C++ though). The ZMQ version is 4.04. The problem I have is that I have a factory class which provides singleton access to zmq context, which is a void pointer created by zmq_ctx_new (). The zmq context itself is stored as a static member variable and a getter method is provided to access reference to this variable. The class itself is quite simple, here is the complete code:

zmq_ctx_factory.h

#include <zmq.h>
#include <cassert>

class ZmqCtxFactory
{
public:
  static void* get_ctx()
  {
    assert (zmq_ctx_ != (void*) NULL);
    return &zmq_ctx_;
  }

  static bool is_initialized()
  {
    return is_initialized_;
  }

  static void init()
  {
    zmq_ctx_ = zmq_ctx_new ();
    is_initialized_ = true;
  }
private:
  static void* zmq_ctx_;
  static bool is_initialized_;
};

zmq_ctx_factory.cpp

#include "zmq_ctx_factory.h"

bool ZmqCtxFactory::is_initialized_ = false;
void* ZmqCtxFactory::zmq_ctx_ = NULL;

Here comes the question, in my client code, below would give an error (error code 14, Bad Address)

void* context = ZmqCtxFactory::get_ctx();
assert (context != (void*) NULL);
socket_ = zmq_socket (context, ZMQ_SUB);

but if I replace ZmqCtxFactory::get_ctx(); with zmq_ctx_new ();, the code works fine. As you can see, I have an assertion to make sure the context is not NULL, that means the ctx variable is created successfully. (as per the document, if the creation failed, zmq_ctx_new () returns NULL). I am confused, why the reference returned by the factory wouldn't work?

Upvotes: 1

Views: 1163

Answers (2)

feng
feng

Reputation: 25

the problem is that static void* get_ctx() doesn't return a reference, it returns address of the void pointer. After changing the method to below the code works fine:

static void*& get_ctx()
  {
    assert (zmq_ctx_ != (void*) NULL);
    return zmq_ctx_;
  }

Upvotes: 1

AlexD
AlexD

Reputation: 32586

ZmqCtxFactory::get_ctx() seems to return the address of the pointer, not the pointer itself.

Try

static void* get_ctx()
{
    assert (zmq_ctx_ != (void*) NULL);
    return zmq_ctx_; // instead of return &zmq_ctx_;
}

Upvotes: 1

Related Questions