2017-08-02 155 views
1

Crypto ++库通过编译cryptlib.libcryptopp.lib来支持后期绑定。这需要使用cryptopp.dll。当试图延迟加载这个dll /DELAYLOAD:cryptopp.dll这会导致一个链接错误,它不能延迟加载,因为所需的导入。延迟加载crypto ++ cryptopp.dll

作为示例,请参见下面的代码:

#include <Crypto++/dll.h> 
#include <crypto++/base64.h> 

bool HexDecode(const std::string& strHex, std::string& strData) 
{ 
    try 
    { 
     CryptoPP::StringSource(strHex, true, 
      new CryptoPP::Base64Decoder(
       new CryptoPP::StringSink(strData))); 
    } 

    catch(...) 
    { 
     return false; 
    } 

    return true; 
} 

这会导致下面的链接错误:

LINK : fatal error LNK1194: Delay loading "cryptopp.dll" not possible because of import of data symbol ""__declspec(dllimport) bool (__cdecl* CryptoPP::g_pAssignIntToInteger)(class type_info const &,void *,void const *)" ([email protected]@@[email protected]@[email protected])". Link without /DELAYLOAD:cryptopp.dll 

有没有人已经成功地延迟加载cryptopp.dll成功?

回答

0

The Crypto++ library supports late binding by compiling against cryptlib.lib and cryptopp.lib...

该DLL是一个FIPS DLL。将功能分成两个独立库的实际目的是提供FIPS 140-2所需的逻辑模块边界。 FIPS模块边界是cryptopp.dll

FIPS DLL只包含FIPS算法,如AES和RSA。我建议你不惜一切代价避免FIPS DLL。这是一个痛苦的工作。另请参阅Crypto ++ wiki上的FIPS DLL

如果您想要一个DLL,然后用您自己的API编写自己的包装器DLL,然后链接到Crypto ++静态库。

在包装DLL的情况下(因为你看起来很有经验),我强烈建议你使用cryptest.nmake作为起点。如果你熟悉makefile(我认为你是),那么你会发现它比Visual Studio project files更容易使用。


LINK : fatal error LNK1194: Delay loading "cryptopp.dll" not possible because of import of data symbol ""__declspec(dllimport) bool (__cdecl* CryptoPP::g_pAssignIntToInteger)(class type_info const &,void *,void const *)" ([email protected]@@[email protected]@[email protected])". Link without /DELAYLOAD:cryptopp.dll

这是一个有趣的问题,因为你有两个库,它的我不明白的符号是在图书馆。第一个库是符合FIPS DLL(cryptopp.dll),它包括AES,RSA等。第二个库是静态库(cryptlib.lib),它包括HexEncoder,FileSource和其他支持的东西。

我认为g_pAssignIntToInteger应该在静态库(cryptlib.lib)中,因为它是AlgorithmParamters的一部分。例如,参见Commit 5efb019d8bdc593b。但是,从上面的错误中,它似乎位于FIPS DLL中,因为符号名称为__imp_?g_pAssignIntToInteger ...

现在增加的皱纹是,g_pAssignIntToInteger是一个函数指针,编译器不会优化它们。所以链接器永远不会丢弃Integer相关的符号,这是解耦的关键。

Commit 0e55f5ac7d98f3c8我们删除了g_pAssignIntToInteger并添加了一个定义CRYPTOPP_NO_ASSIGN_TO_INTEGER来完成任务。该定义确保符号和不需要的代码,如Integer代码可以被丢弃。