The Crypto++ library supports late binding by compiling against cryptlib.lib
and cryptopp.lib
. This requires to use the cryptopp.dll
. When trying to delay-load this dll by /DELAYLOAD:cryptopp.dll
this causes a link error that it could not be delay loaded because of required imports.
As example see the following code:
#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;
}
This causes the following link error:
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 *)" (__imp_?g_pAssignIntToInteger@CryptoPP@@3P6A_NABVtype_info@@PAXPBX@ZA)". Link without /DELAYLOAD:cryptopp.dll
Did anyone already managed to delay load cryptopp.dll
successfully?
The DLL is a FIPS DLL. The actual purpose of splitting functionality into two separate libraries is to provide the logical module boundary required by FIPS 140-2. The FIPS module boundary is
cryptopp.dll
.The FIPS DLL only includes the FIPS algorithms, like AES and RSA. I recommend you avoid the FIPS DLL at all costs. Its a pain to work with. Also see FIPS DLL on the Crypto++ wiki.
If you want a DLL, then write your own wrapper DLL with your own API, and then link to the Crypto++ static library.
In the wrapper DLL case (and since you seem experienced), I highly encourage you to use
cryptest.nmake
as a starting point. If you are familiar with makefiles (I think you are), then you will find it much easier to work with than the Visual Studio project files.This is an interesting question because you have two libraries, and its not clear to me which library the symbol is in. The first library is the FIPS DLL (cryptopp.dll), and it includes AES, RSA, etc. The second library is the Static Lib (cryptlib.lib), and it includes HexEncoder, FileSource, and the other supporting stuff.
I believe
g_pAssignIntToInteger
should be in the Static Lib (cryptlib.lib) because it was part ofAlgorithmParamters
. See, for example, Commit 5efb019d8bdc593b. However, from the error above, it appears to be residing in the FIPS DLL because of the symbol name__imp_?g_pAssignIntToInteger ...
.Now the added wrinkle is,
g_pAssignIntToInteger
is a function pointer, and compilers won't optimize them away. So the linker never discardsInteger
related symbols, which is the point of the decoupling.At Commit 0e55f5ac7d98f3c8 we removed
g_pAssignIntToInteger
and added a defineCRYPTOPP_NO_ASSIGN_TO_INTEGER
to accomplish the task. The define ensures the symbol and unwanted code likeInteger
code can be discarded.