You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编译C++项目遇‘::zoo_create未声明’错误求助

问题描述

编译C++应用时出现如下错误:

/fake/path/ZK_session.cpp: In function 'blah::ZK_result blah::base_create(zhandle_t*, const string&, const string&, const string&, int)':

/fake/path/ZK_session.cpp:202:22: error: '::zoo_create' has not been declared

         auto res = ::zoo_create(zk,

                      ^~~~~~~~~~ 

该问题出现在使用自行从源码编译的Zookeeper客户端库时,此前使用预编译二进制库未出现此问题。

已在Zk_session.h中包含<zookeeper/zookeeper.h>,且该头文件内确实声明了zoo_create()方法,但编译仍报错。

补充怀疑:错误可能与zookeeper.h中的#ifdef THREADED有关——当前使用的是多线程版本客户端zookeeper_mt,但不确定为何THREADED宏未被定义。

相关代码片段

Zk_session.h

#ifndef BLAH_BLAH_ZK_ZK_SESSION_H
#define BLAH_BLAH_ZK_ZK_SESSION_H

#include <functional>
#include <map>
#include <mutex>
#include <fake/path/core.h>
#include <string>
#include <zookeeper/zookeeper.h>

namespace blah
{

...

class ZK_session
{
...
}
}

#endif

Zk_session.cpp

#include <fake/path/ZK_session.h>
#include <sstream>
#include <vector>

#include <iostream>

namespace blah
{
...
ZK_result base_create(::zhandle_t* zk,
                      const std::string& node_path,
                      const std::string& leaf_node_value,
                      const std::string& parent_nodes_value,
                      int leaf_node_type = 0)
{
   ...
        std::string node_str {};
   ...
        bool is_leaf = ss.peek() == std::char_traits<char>::eof();
        auto& value = is_leaf ? leaf_node_value : parent_nodes_value;
        auto type = is_leaf ? leaf_node_type : 0; 
   ...
        auto res = ::zoo_create(zk,
                                node_str.c_str(),
                                value.data(),
                                static_cast<int>(value.size()),
                                &ZOO_OPEN_ACL_UNSAFE,
                                type,
                                nullptr,
                                0);
       ...
    return ZK_result{};
}
...
}

zookeeper.h(片段)

...
#ifdef THREADED
/**
 * \brief create a node synchronously.
 *
 * This method will create a node in ZooKeeper. A node can only be created if
 * it does not already exist. The Create Mode affects the creation of nodes.
 * If ZOO_EPHEMERAL mode is chosen, the node will automatically get removed if the
 * client session goes away. If ZOO_CONTAINER flag is set, a container node will be
 * created. For ZOO_*_SEQUENTIAL modes, a unique monotonically increasing
 * sequence number is appended to the path name. The sequence number is always fixed
 * length of 10 digits, 0 padded.
 *
 * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
 * \param path The name of the node. Expressed as a file name with slashes
 * separating ancestors of the node.
 * \param value The data to be stored in the node.
 * \param valuelen The number of bytes in data. To set the data to be NULL use
 * value as NULL and valuelen as -1.
 * \param acl The initial ACL of the node. The ACL must not be null or empty.
 * \param mode this parameter should be one of the Create Modes.
 * \param path_buffer Buffer which will be filled with the path of the
 *    new node (this might be different than the supplied path
 *    because of the ZOO_SEQUENCE flag).  The path string will always be
 *    null-terminated. This parameter may be NULL if path_buffer_len = 0.
 * \param path_buffer_len Size of path buffer; if the path of the new
 *    node (including space for the null terminator) exceeds the buffer size,
 *    the path string will be truncated to fit.  The actual path of the
 *    new node in the server will not be affected by the truncation.
 *    The path string will always be null-terminated.
 * \return  one of the following codes are returned:
 * ZOK operation completed successfully
 * ZNONODE the parent node does not exist.
 * ZNODEEXISTS the node already exists
 * ZNOAUTH the client does not have permission.
 * ZNOCHILDRENFOREPHEMERALS cannot create children of ephemeral nodes.
 * ZBADARGUMENTS - invalid input parameters
 * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
 * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
 */
ZOOAPI int zoo_create(zhandle_t *zh, const char *path, const char *value,
        int valuelen, const struct ACL_vector *acl, int mode,
        char *path_buffer, int path_buffer_len);

...
#endif
...
解决方案

针对THREADED宏未定义导致zoo_create不可见的问题,按以下步骤排查修复:

  • 编译时显式定义THREADED宏
    在Makefile的C++编译参数中添加-DTHREADED,确保预处理阶段能识别该宏,展开zoo_create的声明。示例:

    CXXFLAGS += -DTHREADED -I/path/to/your/zookeeper/include
    
  • 确认链接多线程版本库
    链接阶段指定zookeeper_mt而非单线程的zookeeper,在Makefile的链接参数中添加:

    LDFLAGS += -L/path/to/your/zookeeper/lib -lzookeeper_mt
    
  • 检查Zookeeper源码编译参数
    若自行编译Zookeeper客户端,需确保开启多线程支持:

    • 用configure编译时,添加--enable-threads参数;
    • 用CMake编译时,设置CMAKE_THREAD_LIBS_INIT并开启WITH_THREADS选项。
  • 验证头文件路径正确性
    确认编译时包含的<zookeeper/zookeeper.h>来自自行编译的Zookeeper库,而非系统默认的旧版本。通过-I参数指定优先搜索的头文件路径,避免版本冲突。

内容的提问来源于stack exchange,提问作者George

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 09:22:06