2017-08-02 158 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代碼可以被丟棄。