Link 在 VS2012 静态库、控制台应用程序和 clr 程序上使用 cryptopp 时出错

Link errors using cryptopp on VS2012 static library, console application and clr program

我在 VS2012 C++ 上有以下项目结构:

cryptopp:从 cryptopp 项目下载和构建。

AccessLib:使用 cryptopp 函数构建的静态库。

TestApp:一个使用 AccessLib(和间接使用 cryptolib)的 Win32 控制台应用程序

UserApp:Windows 具有 CLR 支持的交互式应用程序 (/clr),它使用 AccessLib(和间接使用 cryptolib)

好吧,我的第一个尝试是让这个解决方案能够构建我的控制台应用程序和我的 windows 应用程序。顺便说一句,cryptopp 是按照手册和 this SO link 中描述的方式构建的。来自 cryptopp 项目的所有测试 运行 在构建环境中都很好。

以下是我构建项目的方式:

到目前为止还不错,但是在构建 UserApp 时它不起作用,因为 TestApp 需要 /clr 并且与 MTd/MT 不兼容.

所以,我的第一个问题是:我不能有一个 CLR 程序链接到具有 /MTd/MT 的静态库......我应该怎么做才能构建我的 /clr 程序到我的静态库 AccessLib.lib 也可以作为静态库访问 cryptopp 吗?我是否需要将所有内容都转换为 DLL 项目?

好吧,我什至尝试过将 cryptopp 用作 DLL,这样:

那一步没问题,但是当尝试将 TestApp 构建为也分别用于 Debug 或 Release 的 /MDd/MD 时,链接到从步骤生成的 AccessLib.lib上面,我遇到了几个错误,例如:

 1>------ Build started: Project: TestApp, Configuration: Debug Win32 ------
1>cryptlib.lib(hrtimer.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in TestApp.obj
1>cryptlib.lib(pch.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in TestApp.obj
1>msvcprtd.lib(MSVCP110D.dll) : error LNK2005: "public: __thiscall std::_Container_base12::_Container_base12(void)" (??0_Container_base12@std@@QAE@XZ) already defined in cryptlib.lib(hrtimer.obj)
1>msvcprtd.lib(MSVCP110D.dll) : error LNK2005: "public: __thiscall std::_Container_base12::~_Container_base12(void)" (??1_Container_base12@std@@QAE@XZ) already defined in cryptlib.lib(hrtimer.obj)
1>msvcprtd.lib(MSVCP110D.dll) : error LNK2005: "public: void __thiscall std::_Container_base12::_Orphan_all(void)" (?_Orphan_all@_Container_base12@std@@QAEXXZ) already defined in cryptlib.lib(hrtimer.obj)
1>msvcprtd.lib(MSVCP110D.dll) : error LNK2005: "public: __thiscall std::locale::id::id(unsigned int)" (??0id@locale@std@@QAE@I@Z) already defined in cryptlib.lib(pch.obj)
1>cryptopp.lib(cryptopp.dll) : error LNK2005: "public: unsigned char * __thiscall CryptoPP::AllocatorWithCleanup<unsigned char,0>::allocate(unsigned int,void const *)" (?allocate@?$AllocatorWithCleanup@E[=11=]A@@CryptoPP@@QAEPAEIPBX@Z) already defined in accesslib.lib(Encryptor.obj)
1>cryptopp.lib(cryptopp.dll) : error LNK2005: "public: void __thiscall CryptoPP::AllocatorWithCleanup<unsigned char,0>::deallocate(void *,unsigned int)" (?deallocate@?$AllocatorWithCleanup@E[=11=]A@@CryptoPP@@QAEXPAXI@Z) already defined in accesslib.lib(Encryptor.obj)
1>cryptopp.lib(cryptopp.dll) : error LNK2005: "public: unsigned char * __thiscall CryptoPP::AllocatorWithCleanup<unsigned char,0>::reallocate(unsigned char *,unsigned int,unsigned int,bool)" (?reallocate@?$AllocatorWithCleanup@E[=11=]A@@CryptoPP@@QAEPAEPAEII_N@Z) already defined in accesslib.lib(Encryptor.obj)
1>cryptopp.lib(cryptopp.dll) : error LNK2005: "public: __thiscall CryptoPP::AllocatorWithCleanup<unsigned char,0>::AllocatorWithCleanup<unsigned char,0>(void)" (??0?$AllocatorWithCleanup@E[=11=]A@@CryptoPP@@QAE@XZ) already defined in accesslib.lib(Encryptor.obj)
1>cryptopp.lib(cryptopp.dll) : error LNK2005: "public: __thiscall CryptoPP::Rijndael::Enc::Enc(void)" (??0Enc@Rijndael@CryptoPP@@QAE@XZ) already defined in accesslib.lib(Encryptor.obj)
1>cryptopp.lib(cryptopp.dll) : error LNK2005: "public: virtual __thiscall CryptoPP::Rijndael::Enc::~Enc(void)" (??1Enc@Rijndael@CryptoPP@@UAE@XZ) already defined in accesslib.lib(Encryptor.obj)
1>cryptopp.lib(cryptopp.dll) : error LNK2005: "public: __thiscall CryptoPP::Rijndael::Enc::Enc(class CryptoPP::Rijndael::Enc const &)" (??0Enc@Rijndael@CryptoPP@@QAE@ABV012@@Z) already defined in accesslib.lib(Encryptor.obj)
1>cryptopp.lib(cryptopp.dll) : error LNK2005: "public: static char const * __cdecl CryptoPP::CBC_ModeBase::StaticAlgorithmName(void)" (?StaticAlgorithmName@CBC_ModeBase@CryptoPP@@SAPBDXZ) already defined in accesslib.lib(Encryptor.obj)
1>cryptopp.lib(cryptopp.dll) : error LNK2005: "public: __thiscall CryptoPP::CBC_Encryption::CBC_Encryption(void)" (??0CBC_Encryption@CryptoPP@@QAE@XZ) already defined in accesslib.lib(Encryptor.obj)
1>cryptopp.lib(cryptopp.dll) : error LNK2005: "public: virtual __thiscall CryptoPP::CBC_Encryption::~CBC_Encryption(void)" (??1CBC_Encryption@CryptoPP@@UAE@XZ) already defined in accesslib.lib(Encryptor.obj)
1>cryptopp.lib(cryptopp.dll) : error LNK2005: "public: virtual __thiscall CryptoPP::StreamTransformationFilter::~StreamTransformationFilter(void)" (??1StreamTransformationFilter@CryptoPP@@UAE@XZ) already defined in accesslib.lib(Encryptor.obj)
1>cryptopp.lib(cryptopp.dll) : error LNK2005: "public: __thiscall CryptoPP::StringSinkTemplate<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::StringSinkTemplate<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &)" (??0?$StringSinkTemplate@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@CryptoPP@@QAE@AAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) already defined in accesslib.lib(Encryptor.obj)
1>cryptopp.lib(cryptopp.dll) : error LNK2005: "public: virtual __thiscall CryptoPP::StringSinkTemplate<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::~StringSinkTemplate<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(void)" (??1?$StringSinkTemplate@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@CryptoPP@@UAE@XZ) already defined in accesslib.lib(Encryptor.obj)
1>cryptopp.lib(cryptopp.dll) : error LNK2005: "public: __thiscall CryptoPP::Exception::Exception(enum CryptoPP::Exception::ErrorType,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (??0Exception@CryptoPP@@QAE@W4ErrorType@01@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) already defined in accesslib.lib(Encryptor.obj)
1>LINK : warning LNK4098: defaultlib 'LIBCMTD' conflicts with use of other libs; use /NODEFAULTLIB:library
1>accesslib.lib(Encryptor.obj) : error LNK2001: unresolved external symbol "class CryptoPP::NameValuePairs const & const CryptoPP::g_nullNameValuePairs" (?g_nullNameValuePairs@CryptoPP@@3ABVNameValuePairs@1@B)
1>c:\project\dev\accesslib\Debug\TestApp.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========

我没有使用该配置构建 UserApp

感谢您的帮助,以使整个过程协同工作。我想完全避免使用 DLL。我最初的想法是将所有内容都作为静态库,但我不知道我是否可以在该解决方案配置上实现它。

感谢帮助。

您不能link 将使用MT 或MTd 编译的库编译为使用MD 或MDd 编译的程序。他们有不同的 CRT 库。

您可以使用 MD 或 MDd 重建 cryptopp

That step went fine, but when trying to build TestApp as being also /MDd or /MD for Debug or Release respectively, linking to AccessLib.lib generated from step above, I got several errors like...

您正在混合和匹配运行时。您可能应该更改 Crypto++ 并使其使用动态运行时链接 C/C++ 运行时库。请参阅 Crypto++ wiki 上的 Visual Studio | Dynamic Runtime Linking


I want to avoid usage of DLL´s at all. My original idea is to have everything as static libraries, but I don´t know if I can achieve that on that solution configuration.

是的,这是首选。它可以工作,但您需要使用动态运行时链接构建 Crypto++ 静态库。你要的项目是cryptlib,它的输出在<crypto++ dir>/Output/{Debug|Release}/{Win32|x64}.请参阅前面的链接。

您还应避免使用 FIPS DLL。 DLL工程为cryptdll,其输出在<crypto++ dir>/DLL_Output/...[=56=中]. DLL 是特殊用途的,它只提供 FIPS 算法。它不是一个通用的 DLL,它缺少你需要的大部分东西,它会造成很多痛苦和痛苦。

我什至告诉人们完全删除 cryptdlldlltest 项目,因为它们造成了很多麻烦。另请参阅 Crypto++ wiki 上的 FIPS DLL


Link errors using cryptopp on VS2012 static library, console application and clr program

这是值得注意的...Crypto++ 不使用 /clr 选项。您将需要修改静态库项目设置并添加。

静态库的工程名为cryptlib。您需要为 Win32 DebugWin32 Releasex64 Debugx64 版本.