Ссылка на статическую библиотеку 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".