1)我该如何让用户知道他/她缺少OpenSSL库?(我的朋友报告说没有OpenSSL DLL时也没有异常、错误等提示。)
2)是否有可能让Indy10从资源中读取OpenSSL库?
Indy本身不支持SSL。它实现了一个灵活的IOHandler架构,允许任何SSL实现插入到Indy中。Indy自己实现了基于OpenSSL的IOHandler类(计划在未来支持MS CryptoAPI)。例如,SecureBlackbox为其自己的SSL引擎提供了一个Indy IOHandler类。
在大多数平台上,OpenSSL是通过外部DLL使用的,而这些DLL不能从资源中使用。Indy不随OpenSSL DLL一起提供,因为国际进出口法限制了OpenSSL加密,因此出口国家和地区的操作系统供应商必须拥有特殊许可证才能出售OpenSSL DLL,否则最终用户必须本地下载/编译OpenSSL。这就使Indy在使用OpenSSL方面具有“可移植性”,即Indy使用在Indy之外预先安装的任何OpenSSL DLL,无论是操作系统还是您的应用程序自己的安装文件夹中都可以。
唯一与Indy相关的例外情况是在iOS上使用的OpenSSL,因为iOS设备不允许使用第三方动态库,所以必须静态使用OpenSSL。
如果要在其他平台上静态使用OpenSSL并与Indy配合使用,您需要自己编译/获取静态版本的OpenSSL,并将其添加到您的项目中,然后重新编译Indy以启用其STATICLOAD_OPENSSL
定义(目前仅为iOS定义),最后在代码的uses
子句中包含IdSSLOpenSSLHeaders_static.pas
单元以钩接必要的支持代码。请注意,这仅受新发布的Indy 10.6版本支持。
如果您觉得这太麻烦,那么可以使用与Indy兼容的第三方SSL实现,例如SecureBlackbox,或编写自己的IOHandler类以满足您的需要。
1) 如果在套接字操作期间无法正确加载 OpenSSL,则 Indy 会引发异常。因此,很有可能这些异常被捕获并吞没了,而您没有机会向用户报告它们。如果您不想依赖此功能,则可以在开始套接字工作之前手动调用 Indy 的 IdSSLOpenSSLHeaders.pas
单元中的 Load()
函数。如果 OpenSSL 尚未加载到内存中,Load()
将加载它。如果Load()
失败,则可以调用该单元中的 WhichFailedToLoad()
函数以找出失败的原因。
2) 不,不可能从资源中使用 OpenSSL(除非进行一些非常严重的低级技巧)。
GetModuleHandle()
,而是通过LoadLibrary()
加载DLL,并在不再需要时关闭它们的句柄以进行跟踪。 - Remy Lebeau