如何正确传递 zmq 上下文(void *)?

Posted

技术标签:

【中文标题】如何正确传递 zmq 上下文(void *)?【英文标题】:How to pass zmq context (void *) properly? 【发布时间】:2014-08-16 00:56:17 【问题描述】:

我正在使用 zmq 的原生 C 库来编写我的应用程序(尽管应用程序本身是用 C++ 编写的)。 ZMQ 版本为 4.04。我遇到的问题是我有一个工厂类,它提供对 zmq 上下文的单例访问,这是一个由zmq_ctx_new () 创建的 void 指针。 zmq 上下文本身存储为静态成员变量,并提供了一个 getter 方法来访问对该变量的引用。这个类本身很简单,下面是完整的代码:

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;

问题来了,在我的客户端代码中,下面会给出一个错误(错误代码 14,错误地址)

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

但如果我将ZmqCtxFactory::get_ctx(); 替换为zmq_ctx_new ();,则代码可以正常工作。如您所见,我有一个断言来确保上下文不为 NULL,这意味着 ctx 变量已成功创建。 (根据文档,如果创建失败,zmq_ctx_new () 返回 NULL)。我很困惑,为什么工厂返回的引用不起作用?

【问题讨论】:

【参考方案1】:

ZmqCtxFactory::get_ctx() 似乎返回的是指针的地址,而不是指针本身。

试试

static void* get_ctx()

    assert (zmq_ctx_ != (void*) NULL);
    return zmq_ctx_; // instead of return &zmq_ctx_;

【讨论】:

我在发布后立即想到了同样的事情,将在 7 分钟内接受您的回答。 :) 发布后,我重新阅读了您的问题,并想添加关于通过引用返回的备注。但那时你已经回答了这个问题:)。【参考方案2】:

问题是static void* get_ctx() 没有返回引用,它返回的是 void 指针的地址。将方法更改为下面的代码后工作正常:

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

【讨论】:

以上是关于如何正确传递 zmq 上下文(void *)?的主要内容,如果未能解决你的问题,请参考以下文章

将 ZMQ 上下文传递给线程

Zmq 上下文 - 我应该在新线程中创建另一个上下文吗?

ZeroMQ API 套接字

ZMQ:socket_send/recv 阻塞

在 (void *) 上下文中可以传递啥?

如何检查 googlemock 中作为 void 指针传递的字符串参数