编译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
相关产品推荐
相关产品推荐

