【问题标题】:Openssl unresolved external BN_is_zeroOpenssl 未解析的外部 BN_is_zero
【发布时间】:2015-12-12 12:35:58
【问题描述】:

在使用静态链接的 OpenSSL 1.0.2e 开发一个小项目的过程中,我在 VS13 中遇到了一个奇怪的错误:

Error LNK2001: unresolved external symbol _BN_is_zero

当您忘记在项目属性中正确点赞 .lib 文件时,通常会发生这种情况,但所有属性都经过了双重检查 - 它们都是正确的。

配置 - ReleaseMTlibs 包括 MTbh.h

即使其中一个库没有正确链接,我应该有多个编译器错误抱怨项目中使用的所有元素的未解析外部符号,但在我的情况下,未解析的外部符号是唯一的 BN_is_zero

在快速谷歌搜索后,没有发现任何与 openssl 错误相关的问题,我猜问题出在我的项目中。

任何提示将不胜感激。

UPD

这是一些屏幕:

【问题讨论】:

  • 链接器可能会在第一个未解析的符号处停止,我不确定。发布一个屏幕截图可能会有所帮助,显示您在链接器设置中包含 OpenSSL 库的位置。
  • @JonathonReinhart 完成

标签: c visual-studio linker openssl


【解决方案1】:

实际上,我分叉了 csrp github 项目,并针对您所指向的特定 openssl 库对其进行了编译。我不得不稍微修改 test_srp.c 和 src.c 以添加一些 VS2013 上不可用的代码。可以在此处找到已应用更改的 csrp 分支以及用于 VS2013 的 Visual Studio 项目来编译它:

https://github.com/sigmoidal/csrp

请注意,您需要在 BOTH 调试和发布版本上更改 openssl 路径的路径以反映您的 VS 配置属性:

  • C/C++ > 常规 > 附加包含目录

     D:\dev\openssl\openssl-1.0.2e-vs2013\include

    (你不应该将它指向 $openssl_path/include/openssl,它不会工作)

还有:

  • 链接器>输入>附加依赖:

    • 对于发布配置:

      D:\dev\openssl\openssl-1.0.2e-vs2013\lib\libeay32MT.lib
      D:\dev\openssl\openssl-1.0.2e-vs2013\lib\ssleay32MT.lib
    • 调试配置:

      D:\dev\openssl\openssl-1.0.2e-vs2013\lib\libeay32MTd.lib
      D:\dev\openssl\openssl-1.0.2e-vs2013\lib\ssleay32MTd.lib

    (注意调试库上的“d”后缀)

为我编译好了。

【讨论】:

  • 从您的存储库中获取了一些代码,但在运行时失败。没时间自己调试。
  • 该项目运行良好,问题是您指向我们的代码,test_srp.c 的代码在 VS2013 中无法编译。我将需要修改的 test_srp.c 代码替换为 github 项目的使用示例中显示的代码,然后重新编译并运行它,而 OpenSSL 1.0.2e 没有问题。请注意,您犯了一个可怕的错误,从旧版本中获取 bn.h 并使用它来编译不同的库。 #defines 可能会采用可能导致严重问题的意外值。
  • 也许你是对的。我会仔细比较我和你的解决方案的结果
  • 不需要比较任何东西,只需再次下载github(我更新了包含main的fine)并编译,它工作正常,没有运行时崩溃。确保您正确使用调试/发布。对我来说很好。
【解决方案2】:

我在这里猜测,但根据 OpenSSL 源 BN_is_zero 被定义为宏:

http://osxr.org/openssl/source/crypto/bn/bn.h#0407

所以也许编译成srp.obj的模块正在调用BN_is_zero,但不包括bn/bn.h,并且在没有原型的情况下,编译器正在生成一个默认的。

如果是这种情况,包括bn.h 定义应该避免链接器错误。

【讨论】:

  • 已包含在内。或者你的意思是其他的 bn.h?
  • 我的意思是bn.h。你能在srp.obj 的源代码中看到对BN_is_zero 的调用吗? srp.obj 是您的代码吗?它有所有必要的#include 指令吗?
  • 是的,它包含所有需要的内容。一般来说,我正在尝试构建这个项目github.com/cocagne/csrp,这样你就可以自己看到它 - 所需的一切都包括在内。
【解决方案3】:

这很棘手,但我终于根据 Drew MacInnis 的提示解决了这个问题。 问题是 openssl 1.0.2e 通过简单地从源中删除包含宏的标头来破坏BN_is_zero 功能。所以,解决办法是:

  1. 1.0.1h(或here)下载bn.h包含文件
  2. 将bn.h放到%OPENSSL_HOME%/crypto/bn目录下
  3. #include <openssl/bn.h> 更改为#include <../crypto/bn/bn.h>

【讨论】:

  • 但你甚至都不赞成 Drew。您也可以用您的解决方案更新他的答案。而且,如果您发布答案,您也应该接受它。
猜你喜欢
  • 2020-03-03
  • 1970-01-01
  • 2015-08-17
  • 2013-11-23
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
  • 2011-02-09
相关资源
最近更新 更多