如何在 Windows 下获取线程安全的 libssh2 链接?

How to get thread-safe libssh2 to link under Windows?

提问人:Jeremy Friesner 提问时间:12/9/2011 更新时间:12/9/2011 访问量:1774

问:

我正在开发一个使用 libssh2 的多线程、多平台、基于 Qt 的程序。当几个使用 SSH 的线程同时处于活动状态时,该程序偶尔会在 crypt_encrypt() 和 libssh2_transport_write() 中崩溃,所以我用谷歌搜索了一下,发现一些页面说要使多线程 libssh2 可靠地工作,我需要在使用 libssh2 之前调用 CRYPTO_set_locking_callback() 等。

根据该建议,我在 main() 的顶部添加了指定的回调设置调用,并让它全部编译和运行而不会在 MacOS/X 下崩溃......但在 Windows 下,我现在收到以下链接错误,我不确定如何修复。

Microsoft (R) Windows (R) 资源编译器版本 6.1.6723.1 版权所有 (C) Microsoft Corporation。保留所有权利。 连接。。。 main.obj:错误 LNK2019:函数“void __cdecl do_crypto_locks_setup(void)”(?do_crypto_locks_setup@@YAXXZ) 中引用了未解析的外部符号_CRYPTO_set_locking_callback main.obj:错误 LNK2019:函数“void __cdecl do_crypto_locks_setup(void)”(?do_crypto_locks_setup@@YAXXZ) 中引用了未解析的外部符号_CRYPTO_malloc main.obj:错误 LNK2019:函数“void __cdecl do_crypto_locks_setup(void)”(?do_crypto_locks_setup@@YAXXZ) 中引用了未解析的外部符号_CRYPTO_num_locks main.obj:错误 LNK2019:函数“void __cdecl do_crypto_locks_cleanup(void)”(?do_crypto_locks_cleanup@@YAXXZ) 中引用了未解析的外部符号_CRYPTO_free

有谁知道我可能需要做什么才能在 Windows 下链接这些调用?我是否需要链接其他一些 .lib 文件,或者我是否需要将特定标志传递给“perl Configure VC-WIN32”命令以启用这些功能,或者???

谢谢 杰里米

Windows 多线程未 解析的外部 libssh2

评论

0赞 RedComet 12/9/2011
也许您应该尝试使用 MinGw QT 工具链。这些通常更适合与 unix 派生的库一起使用,如 libssh2、zlib、pcre、glib 等
0赞 Jeremy Friesner 12/9/2011
我不认为这对我来说是一个选择;我正在调试的是别人的程序,我不能现实地要求他们仅仅为了支持错误修复而更改整个工具链。

答:

0赞 RedComet 12/9/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 部分。

    EXPORTS
      my_exported_function
      my_other_exported_function

剩下的就是让 MacOSX 开发人员搜索这些函数,并告诉您哪个特定库具有这些函数,重新检查代码,如果可以,请重新声明,然后重试。

对不起,我无法确切地指出您的问题是什么。

还要记住,Visual Studio 是 C++ 编译器,而不是 C 编译器,虽然它几乎符合 C90,但 libssh 库或其他库可以使用一些 VS 不支持的 C99 构造。

我希望这能以某种方式帮助你找到自己的路。

评论

0赞 Jeremy Friesner 12/9/2011
这很有帮助,谢谢!然而,即使在我链接了我的程序之后,我的回调例程也没有按照文档被调用;我不确定为什么,但我怀疑一些问题与 OpenSSL 如何嵌入 Libssh2 有关,然后我的应用程序链接到该 Libssh2。我最终的(丑陋的)解决方案是将 CRYPTO_set*() 调用从我的应用程序移动到 libssh2_init() 函数中,因为它们从那里正常工作。由于该应用程序附带了libssh2.dll的副本,这对我来说已经足够了,尽管它根本不是一个优雅的解决方案。