Openssl 未解析的外部 BN_is_zero
Openssl unresolved external BN_is_zero
在使用静态链接的OpenSSL 1.0.2e开发一个小项目的过程中,我在VS13中遇到了一个奇怪的错误:
Error LNK2001: unresolved external symbol _BN_is_zero
经常发生这种情况,因为您忘记在项目属性中适当地喜欢 .lib
文件,但所有属性都经过仔细检查 - 它们都是正确的。
配置 - Release
、MT
、libs 包含 MT
、bh.h
。
即使其中一个库没有正确链接,我也应该有多个编译器错误抱怨项目中使用的所有元素的未解析外部符号,但在我的情况下,未解析的外部符号是唯一的 BN_is_zero
.
快速谷歌搜索后没有发现任何与 openssl 错误相关的问题,我想问题出在我的项目上。
如有任何提示,我们将不胜感激。
UPD
这是一些屏幕:
我在这里猜测,但根据 OpenSSL 源 BN_is_zero
被定义为宏:
http://osxr.org/openssl/source/crypto/bn/bn.h#0407
所以也许被编译成 srp.obj
的模块正在调用 BN_is_zero
但不包括 bn/bn.h
并且在没有原型的情况下编译器正在生成一个默认值一。
如果是这种情况,包括 bn.h
定义应该可以避免链接器错误。
这很棘手,但我最终根据 Drew MacInnis 的提示解决了它。
问题是 openssl 1.0.2e 通过简单地从源中删除 macros-containing header 破坏了 BN_is_zero
功能。所以,解决方案是:
- 从
1.0.1h
(或 here) 下载 bn.h 包含文件
- 将bn.h放入
%OPENSSL_HOME%/crypto/bn
目录
- 将
#include <openssl/bn.h>
更改为 #include <../crypto/bn/bn.h>
我实际上分叉了 csrp github 项目并针对您指向的特定 openssl 库编译了它。我不得不稍微修改 test_srp.c 和 src.c 以添加一些在 VS2013 上不可用的代码。可以在此处找到应用了更改的 csrp 分支和用于 VS2013 编译它的 visual studio 项目:
https://github.com/sigmoidal/csrp
请注意,您需要在 调试和发布版本上更改 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" 后缀)
编译对我来说没问题。
在使用静态链接的OpenSSL 1.0.2e开发一个小项目的过程中,我在VS13中遇到了一个奇怪的错误:
Error LNK2001: unresolved external symbol _BN_is_zero
经常发生这种情况,因为您忘记在项目属性中适当地喜欢 .lib
文件,但所有属性都经过仔细检查 - 它们都是正确的。
配置 - Release
、MT
、libs 包含 MT
、bh.h
。
即使其中一个库没有正确链接,我也应该有多个编译器错误抱怨项目中使用的所有元素的未解析外部符号,但在我的情况下,未解析的外部符号是唯一的 BN_is_zero
.
快速谷歌搜索后没有发现任何与 openssl 错误相关的问题,我想问题出在我的项目上。
如有任何提示,我们将不胜感激。
UPD
这是一些屏幕:
我在这里猜测,但根据 OpenSSL 源 BN_is_zero
被定义为宏:
http://osxr.org/openssl/source/crypto/bn/bn.h#0407
所以也许被编译成 srp.obj
的模块正在调用 BN_is_zero
但不包括 bn/bn.h
并且在没有原型的情况下编译器正在生成一个默认值一。
如果是这种情况,包括 bn.h
定义应该可以避免链接器错误。
这很棘手,但我最终根据 Drew MacInnis 的提示解决了它。
问题是 openssl 1.0.2e 通过简单地从源中删除 macros-containing header 破坏了 BN_is_zero
功能。所以,解决方案是:
- 从
1.0.1h
(或 here) 下载 bn.h 包含文件
- 将bn.h放入
%OPENSSL_HOME%/crypto/bn
目录 - 将
#include <openssl/bn.h>
更改为#include <../crypto/bn/bn.h>
我实际上分叉了 csrp github 项目并针对您指向的特定 openssl 库编译了它。我不得不稍微修改 test_srp.c 和 src.c 以添加一些在 VS2013 上不可用的代码。可以在此处找到应用了更改的 csrp 分支和用于 VS2013 编译它的 visual studio 项目:
https://github.com/sigmoidal/csrp
请注意,您需要在 调试和发布版本上更改 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" 后缀)
编译对我来说没问题。