文章目录
1. 概述
ZeroMQ(Zero Message Queue)是一个开源的高性能消息传递库,用于实现异步消息传递和多线程通信。支持跨平台,可在多种操作系统环境下使用。
本教程主要为Windows操作系统下使用Visual Studio 2017来编译ZMQ源码,其编译过程较为复杂,中途可能会出现很多报错,需要一步一步仔细的去分析并处理这些问题,一套流程下来,基本上是可以成功编译的。内容虽繁琐,但也是一个学习的过程。
2. 下载zmq源码
通过官网下载zmq源码,本次教程中所使用的版本为V4.3.2,该版本不是最新也不至于太旧,适合项目中使用。下载连接为:zmq v4.3.2
3. 打开项目并编译
zmq官方提供了VS编译的途径,目前支持最新的VS版本为VS2017。源码下载完毕后解压到指定位置,找到项目工程文件并使用VS2017打开项目。
(1)找到并打开工程
工程的位置:
..\libzmq-4.3.2\builds\deprecated-msvc\vs2017\
工程文件:
libzmq.sln
使用VS2017打开项目工程文件
libzmq-4.3.2\builds\deprecated-msvc\vs2017\libzmq.sln
(2)编译libzmq项目
打开后在解决方案中可以看到7个项目,首先编译libzmq项目,右键该项目,点击生成。
不出意外的话,这一步会报错😂,接着往下看。
4. 报错解决:找不到windows SDK版本8.1
错误信息:找不到windows SDK版本8.1
解决方法更换Windows SDK版本选择10.0版本,记得将编译平台设置为x64,我们需要的是64位环境编译,如果需要32位的库则选Win32编译。
设置好后继续编译libzmq项目。
5. 报错解决:None of the ZMQ_IOTHREAD_POLLER_USE_*
错误信息:错误 C1189 #error: None of the ZMQ_IOTHREAD_POLLER_USE_* macros defined (编译源文件 ..\..\..\..\src\devpoll.cpp) libzmq d:\cpp_env\libzmq-4.3.2\src\poller.hpp
这个错误表明在编译源文件
devpoll.cpp
时,没有定义任何
ZMQ_IOTHREAD_POLLER_USE_*
宏。
这些宏通常用于指定 ZeroMQ 库中的 I/O 线程轮询器(I/O Thread Poller)的实现。I/O 线程轮询器是 ZeroMQ 库中的一个组件,用于处理底层的 I/O 事件,比如套接字的可读或可写事件。
要解决这个错误,你需要在编译源文件之前确保定义了适当的宏。你可以根据你的需求,在编译命令中定义一个适当的宏,这些宏的具体定义取决于你所使用的操作系统和编译环境。
出现该报错原因是缺少下面两个宏定义
ZMQ_IOTHREAD_POLLER_USE_SELECT
ZMQ_POLL_BASED_ON_SELECT
将这两个宏定义添加到项目中,在libzmq属性页 -> 配置属性 -> C/C++ -> 预处理器 -> 预处理器定义
点击编辑,将上面两个宏定义粘贴进去。
继续编译。
6. 报错解决:C3646 “_cond_var”: 未知重写说明符
错误信息:错误 C3646 “_cond_var”: 未知重写说明符 (编译源文件 ..\..\..\..\src\mailbox_safe.cpp) libzmq d:\cpp_env\libzmq-4.3.2\src\mailbox_safe.hpp
双击该错误,可以定位到
mailbox_safe.hpp
文件,该变量的定义位置
condition_variable_t _cond_var
可以看到该
_cond_var
变量在此处是被申明了,那么为什么在编译报错未申明呢?
按住ctrl点击进去
condition_variable_t
类的实现
其实在这里已经发现了问题所在,这个
condition_variable_t
类的定义是处于条件编译分支中,取决于对应的宏有没有被定义
zmq支持的宏有:
ZMQ_USE_CV_IMPL_NONE
: 这意味着不使用条件变量。这通常意味着你要使用其他方式来实现线程同步,或者你的应用程序只有单个线程。
ZMQ_USE_CV_IMPL_WIN32API
: 这个宏指示ZMQ使用Windows操作系统提供的条件变量实现。
ZMQ_USE_CV_IMPL_STL11
: 这表示ZMQ使用C++11标准库中提供的条件变量实现。
ZMQ_USE_CV_IMPL_VXWORKS
: 这是指示在VxWorks实时操作系统上使用的条件变量实现。
ZMQ_USE_CV_IMPL_PTHREADS
: 这个宏表示ZMQ将使用POSIX线程库(pthread)提供的条件变量实现。
这些宏是ZeroMQ (ZMQ) 库用于控制条件变量实现的选项。条件变量是一种线程间同步的机制,它允许线程在满足某个特定条件之前等待。不同的操作系统和库提供了不同的条件变量实现。你可以根据你的目标平台和需求选择合适的条件变量实现。
因此在项目的宏定义中添加上对应的宏即可,这里选取第二个宏,将其添加至预处理器定义中。
继续编译。
7. 报错解决:无法解析的外部符号 "struct zmq::endpoint_uri_pair_t __cdecl
错误信息:错误 LNK2019 无法解析的外部符号 "struct zmq::endpoint_uri_pair_t __cdecl zmq::make_unconnected_connect_endpoint_pair(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?make_unconnected_connect_endpoint_pair@zmq@@YA?AUendpoint_uri_pair_t@1@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z),该符号在函数 "public: int __cdecl zmq::socket_base_t::connect(char const *)" (?connect@socket_base_t@zmq@@QEAAHPEBD@Z) 中被引用 libzmq D:\CPP_ENV\libzmq-4.3.2\builds\deprecated-msvc\vs2017\libzmq\socket_base.obj
这个错误(LNK2019)通常是链接错误,表明编译器找不到对应的函数或变量的定义。在这种情况下,编译器无法找到函数
zmq::make_unconnected_connect_endpoint_pair
的定义,该函数在
zmq::socket_base_t::connect
中被引用。
解决办法:在
libzmq-4.3.2\src
找到对应的依赖文件并引入项目中
在项目
src\include
目录中添加现有项:
endpoint.hpp
stream_listener_base.hpp
stream_connecter_base.hpp
ip_resolver.hpp
在项目
src
目录中添加现有项:
endpoint.cpp
stream_listener_base.cpp
stream_connecter_base.cpp
ip_resolver.cpp
继续编译。
8. libzmq项目编译通过
9. 重新生成整个解决方案
右键解决方案,重解决方案目标
生成解决方案。
10. 报错解决:无法打开文件“libzmq.lib”
错误信息:错误 LNK1104 无法打开文件“libzmq.lib” inproc_lat D:\CPP_ENV\libzmq-4.3.2\builds\deprecated-msvc\vs2017\inproc_lat
错误原因是无法链接到生成
libzmq.lib
库
解决方案:修改项目配置文件
zmq
库链接路径,该配置文件路径为:
libzmq-4.3.2\builds\deprecated-msvc\vs2017\libzmq.import.props
将
..\libzmq\
该路径去掉。
重新生成解决方案
11. 编译成功
在
zmq
目录
\libzmq-4.3.2\bin\x64\Debug\v141\dynamic
下会生成两个库文件:
libzmq.dll
libzmq.lib
引入到需要使用的项目即可。
版权归原作者 Sonny叔 所有, 如有侵权,请联系我们删除。