Ссылка на статическую библиотеку 0MQ в VS

Это может быть вопрос Visual Studio больше, чем что-либо еще...
Я пытаюсь построить пример 0MQ С++ с использованием VS10 и ZeroMQ 2.2.0.
Я загрузил источники Windows и попытался выполнить эти инструкции в чтобы построить 0MQ статически. В частности:

  • Отключено к выпуску
  • Для всех 7 проектов в решении:
    • установите General\Configuration Type в Static library (.lib)
    • установите C/C++\Code Generation\Runtime Library в Multi-threaded (/MT)
    • добавлен ZMQ_STATIC в C/C++\Preprocessor\Preprocessor Definitions
  • Обновлены zmq.h и zmq_utils.h, так что если _MSC_VER и ZMQ_STATIC определены, то DLL_EXPORT также будет определен

В этот момент 0MQ, похоже, хорошо строится.

  • Создан пустой консольный проект:
    • переключился на Release
    • добавлен один файл cpp с приведенным выше примером
      • изменил random на rand, srandom на srand и snprintf на _snprintf
    • установите C/C++\Code Generation\Runtime Library в Multi-threaded (/MT)
    • добавлена ​​папка ...\zeromq-2.2.0\include в C/C++\General\Additional Include Directories
    • добавлен ...\zeromq-2.2.0\builds\msvc\Release\*.lib в Linker\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

Что я пропустил?

Ответ 1

Вы должны добавить ZMQ_STATIC в C/C++\Preprocessor\Preprocessor Definitions в свой "пустой проект консоли". В противном случае при компиляции приложения ZMQ_EXPORT в zmq.h определяется как __declspec(dllimport), и в результате MSVC ищет __imp__zmq_* символы вместо zmq_*

Ответ 2

У меня были аналогичные ошибки - не при попытке статической ссылки, а просто в попытке создать проект ZMQ и связать ".bub" с заглушками для DLL.

В моем случае это было потому, что я пытался связать 64-битные библиотеки с 32-разрядным проектом. Я загрузил неправильную версию. Когда я получил правильные, то есть x86 вместо x64, он работал.

Ответ 3

Является ли статическая связь очень важной для вас? Если нет, вы можете попробовать второй ответ 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/С++ → Общие → Дополнительные каталоги Include" и добавьте C:\dev\zeromq\include. Это будет ссылаться на файлы заголовков 0MQ.
    • Перейдите к "Linker → Input → Additional Dependencies" и добавьте полный путь к файлу "libzmq.dll" с предыдущего шага.
    • Создайте свой проект - теперь это должно идти без ошибок.
  • Скопировать 'libzmq.dll' в ту же папку, что и ваш исполняемый файл, - теперь ваш проект должен работать.

Некоторые комментарии:

  • Я не уверен, зачем вам ссылаться на файл libzmq.lib. Исполняемый файл не нужен (вы можете удалить его, и он все равно будет работать, поскольку необходимая логика находится в dll). Может кто-нибудь объяснить это?
  • Обратите внимание на одно из предостережений в примере для пользователей Windows - второй оператор привязки (publisher.bind("ipc://weather.ipc");) вызовет исключение. Как объясняется здесь (хотя и в мелкой печати), межпроцессный транспорт не поддерживается в Windows.

ИЗМЕНИТЬ

Я думаю, что ответ на мой первый комментарий можно найти в MSDN:

"Когда исходный код исполняемого файла скомпилирован или собран, вызов функции DLL генерирует ссылку на внешнюю функцию в объектном коде. Чтобы устранить эту внешнюю ссылку, приложение должно ссылаться на библиотеку импорта (файл .lib) предоставленный разработчиком DLL".