Как получить потокобезопасную libssh2 для линковки под Windows?

Я работаю над многопоточной многоплатформенной программой на основе Qt, которая использует libssh2. Программа иногда давала сбой внутри crypt_encrypt () и libssh2_transport_write () при одновременной активности нескольких потоков, использующих SSH, поэтому я поискал в Google и нашел некоторые страницы, в которых говорится, что для надежной работы многопоточной библиотеки libssh2 мне нужно вызвать CRYPTO_set_locking_callback () и т. д. перед использованием libssh2.

Основываясь на этом совете, я добавил указанные вызовы callback-setup в начало main () и заставил все это скомпилировать и запустить без сбоев под MacOS / X ... но под Windows теперь я получаю следующие ошибки ссылок, которые я не знаю как исправить.

Компилятор ресурсов Microsoft (R) Windows (R) Версия 6.1.6723.1 Авторские права (C) Корпорация Microsoft. Все права защищены. Связывание ... main.obj: ошибка LNK2019: неразрешенный внешний символ _CRYPTO_set_locking_callback, указанный в функции "void __cdecl do_crypto_locks_setup (void)" (? Do_crypto_locks_setup @@ YAXXZ) main.obj: error LNK_locks_setup @@YAXXZ) do_crypto_locks_setup (void) "(? do_crypto_locks_setup @@ YAXXZ) main.obj: error LNK2019: неразрешенный внешний символ _CRYPTO_num_locks, на который ссылается функция" void __cdecl do_crypto_locks_setup (void_Num_locks) "(? символ _CRYPTO_free, указанный в функции "void __cdecl do_crypto_locks_cleanup (void)" (? do_crypto_locks_cleanup @@ YAXXZ)

Кто-нибудь знает, что мне нужно сделать, чтобы связать эти вызовы под Windows? Есть ли какой-то другой файл .lib, который мне нужно связать, или мне нужно передать определенный флаг команде "perl Configure VC-WIN32", чтобы включить эти функции, или ???

Спасибо Джереми


person Jeremy Friesner    schedule 08.12.2011    source источник
comment
Возможно, вам стоит попробовать с набором инструментов MinGw QT. Обычно их лучше использовать с производными библиотеками unix, такими как libssh2, zlib, pcre, glib и т. Д.   -  person RedComet    schedule 08.12.2011
comment
Я не думаю, что это вариант для меня; это чужая программа, которую я отлаживаю, и я не могу реально попросить их изменить всю их цепочку инструментов только для поддержки исправления ошибок.   -  person Jeremy Friesner    schedule 09.12.2011


Ответы (1)


Не уверен, что это поможет, но эта ссылка: http://www.lurklurk.org/linkers/linkers.html

перечислите некоторые различия между ссылками на unix и windows

Отрывок:

Самая большая разница между ними заключается в том, что символы не экспортируются автоматически библиотеками Windows. В Unix все символы из всех объектных файлов, которые были связаны в общую библиотеку, видны пользователям библиотеки. В Windows программист должен явно выбрать отображение определенных символов, т. Е. экспортировать их.

Есть три способа экспортировать символ из Windows DLL (и все три способа могут быть смешаны вместе в одной библиотеке).

In the source code, declare the symbol as `__declspec(dllexport)`, thusly:

__declspec (dllexport) int my_exported_function (int x, double y);

On the invocation of the linker, use the /export:symbol_to_export option to LINK.EXE.

    LINK.EXE /dll /export:my_exported_function

Get the linker to pull in a module definition (.DEF) file (by using the /DEF:def_file linker option), and in that file include an

Раздел ЭКСПОРТ, содержащий символы, которые вы хотите экспортировать.

    EXPORTS
      my_exported_function
      my_other_exported_function

Осталось бы попросить разработчиков MacOSX найти эти функции и сообщить вам, в какой конкретной библиотеке есть эти функции, перепроверить код, повторно объявить, если можете, и повторить попытку.

Извините, что я не смог точно указать, в чем ваша проблема.

Также имейте в виду, что Visual Studio - это компилятор C ++, а не компилятор C, и, хотя он почти совместим с C90, библиотеки libssh или другие могут использовать некоторые конструкции C99, которые VS не поддерживает.

Надеюсь, это как-то поможет тебе сориентироваться.

person RedComet    schedule 08.12.2011
comment
Это было полезно, спасибо! Однако даже после того, как я получил ссылку на свою программу, мои процедуры обратного вызова не вызывались, как описано в документации; Я не уверен, почему, но подозреваю, что есть проблема, связанная с тем, как OpenSSL встроен в Libssh2, который затем связан с моим приложением. Мое возможное (уродливое) решение заключалось в том, чтобы переместить вызовы CRYPTO_set * () из моего приложения в функцию libssh2_init (), поскольку они работают правильно оттуда. Поскольку приложение поставляется с копией libssh2.dll, мне этого достаточно, хотя это совсем не изящное решение .... - person Jeremy Friesner; 09.12.2011