12

这可能是一个 Visual Studio 问题,最重要的是......
我正在尝试使用 VS10 和 ZeroMQ 2.2.0构建一个 0MQ C++ 示例。
我下载了Windows 源代码并尝试按照这些说明静态构建 0MQ。具体来说:

  • 切换到发布
  • 对于解决方案中的所有 7 个项目:
    • 设置General\Configuration TypeStatic library (.lib)
    • 设置C/C++\Code Generation\Runtime LibraryMulti-threaded (/MT)
    • 添加ZMQ_STATICC/C++\Preprocessor\Preprocessor Definitions
  • 更新了zmq.hzmq_utils.h因此如果_MSC_VERZMQ_STATIC被定义,那么DLL_EXPORT也将被定义

此时 0MQ 似乎构建良好。

  • 创建了一个空的控制台项目:
    • 切换到发布
    • 使用上面链接的示例添加了一个 cpp 文件
      • 更改randomrand, srandomtosrandsnprintfto_snprintf
    • 设置C/C++\Code Generation\Runtime LibraryMulti-threaded (/MT)
    • ...\zeromq-2.2.0\include文件夹添加到C/C++\General\Additional Include Directories
    • 添加...\zeromq-2.2.0\builds\msvc\Release\*.libLinker\Input\Additional Dependencies

但是我仍然收到以下链接错误:

1>zmqexp.obj : error LNK2001: unresolved external symbol __imp__zmq_bind
1>zmqexp.obj : error LNK2001: unresolved external symbol __imp__zmq_close
1>zmqexp.obj : error LNK2001: unresolved external symbol __imp__zmq_errno
1>zmqexp.obj : error LNK2001: unresolved external symbol __imp__zmq_init
1>zmqexp.obj : error LNK2001: unresolved external symbol __imp__zmq_msg_data
1>zmqexp.obj : error LNK2001: unresolved external symbol __imp__zmq_strerror
1>zmqexp.obj : error LNK2001: unresolved external symbol __imp__zmq_socket
1>zmqexp.obj : error LNK2001: unresolved external symbol __imp__zmq_msg_init_size
1>zmqexp.obj : error LNK2001: unresolved external symbol __imp__zmq_term
1>zmqexp.obj : error LNK2001: unresolved external symbol __imp__zmq_msg_close
1>zmqexp.obj : error LNK2001: unresolved external symbol __imp__zmq_send

我错过了什么?

4

3 回答 3

17

您也应该ZMQ_STATICC/C++\Preprocessor\Preprocessor Definitions“空控制台项目”中添加。否则,当您编译应用程序时,ZMQ_EXPORTinzmq.h被定义为__declspec(dllimport),因此,MSVC 会查找__imp__zmq_*符号而不是zmq_*

于 2012-04-29T12:41:01.063 回答
5

我有类似的错误 - 不是在尝试静态链接时,而是只是尝试创建一个 ZMQ 项目并为 dll 链接 .lib 'stubs'。

就我而言,这是因为我试图将 64 位库链接到 32 位项目中。我下载了错误的版本。当我得到正确的,即 x86 而不是 x64 时,它就起作用了。

于 2013-12-30T18:37:12.543 回答
2

静态链接对您来说很重要吗?如果没有,您可以在此处尝试 elnino_9 的第二个答案。详细阐述 elnino_9 的答案:

  • 下载源代码并解压缩到某个本地文件夹(比如 C:\dev\zeromq)。
  • 转到 C:\dev\zeromq-2.2.0\builds\msvc 并打开 msvc.sln 解决方案。MS2010 将从 VS2008 升级到 VS2010 项目
  • 构建所有项目。
  • 构建应生成以下两个文件:
    • C:\dev\zeromq\lib\libzmq.lib - 这是您需要在项目的链接器选项中引用的内容
    • C:\dev\zeromq_boaz\builds\msvc\Release\libzmq.dll - 您需要将其复制到与项目可执行文件相同的文件夹才能运行它(如果您的构建配置为“调试”,则路径将是 C:\dev\zeromq\builds\msvc\ Debug \libzmq.dll)
  • 创建您的解决方案和项目。请执行下列操作:
    • 在解决方案资源管理器中,右键单击您的项目,然后选择“属性”(在最底部)。
    • 导航到“C/C++ --> 常规 --> 附加包含目录”并添加 C:\dev\zeromq\include。这将引用 0MQ 的头文件。
    • 导航到“链接器-->输入-->附加依赖项”并将完整路径添加到上一步中的“libzmq.dll”文件。
    • 构建您的项目 - 现在应该没有错误了。
  • 将“libzmq.dll”复制到与您的可执行文件相同的文件夹中——您的项目现在应该可以运行了。

一些评论:

  • 我不确定您为什么需要引用“libzmq.lib”文件。可执行文件不需要它(您可以删除它,它仍然会运行,因为必要的逻辑驻留在 dll 中)。有人可以解释一下吗?
  • 请注意示例中针对 Windows 用户的一个警告 - 第二个绑定语句 ( publisher.bind("ipc://weather.ipc");) 将导致异常。正如这里所解释的(虽然在细则中),Windows 不支持进程间传输。

编辑

我认为我的第一条评论的答案可以在MSDN中找到:

“在编译或汇编调用可执行文件的源代码时,DLL 函数调用会在目标代码中生成一个外部函数引用。要解析这个外部引用,应用程序必须链接到由DLL 的制造商。”

于 2012-04-30T07:26:17.440 回答