【发布时间】:2016-03-14 23:59:16
【问题描述】:
我在VS2012 C++上有如下项目结构:
cryptopp:从 cryptopp 项目下载和构建。
AccessLib:使用 cryptopp 函数构建的静态库。
TestApp:一个 Win32 控制台应用程序,它使用 AccessLib(和 cryptolib 间接)
UserApp:具有 CLR 支持 (/clr) 的 Windows 交互式应用程序,它使用 AccessLib(和 cryptolib 间接)
嗯,我的第一次尝试是让这个解决方案工作以构建我的控制台应用程序和我的 Windows 应用程序。顺便说一句,cryptopp 是按照手册和this SO link 中描述的方式构建的。 cryptopp 项目的所有测试在构建环境中运行良好。
这是我构建项目的方式:
将
AccessLib分别设置为/Mtd或/MT用于Debug或Release,分别与cryptodir\Win32\Output\Debug和cryptodir\Win32\Output\Release中的cryptolib.lib链接。将
TestApp设置为/MTd或/MT分别用于Debug 或Release,链接到上述步骤生成的AccessLib.lib。
到目前为止还可以,但是在构建 UserApp 时,它不能工作,因为 TestApp 需要 /clr 并且这与 MTd 或 /MT 不兼容。
所以,这是我的第一个问题:我不能有一个 CLR 程序链接到具有 /MTd 或 /MT... 的静态库。我应该怎么做才能构建我的 /clr 程序我的静态库AccessLib.lib 也作为静态库访问cryptopp 吗?我是否需要将所有内容都转换为 DLL 项目?
好吧,我什至尝试转换为使用cryptopp作为DLL,这样:
- 将
AccessLib设置为/MDd或/MD分别用于调试或发布,分别与cryptodir\Win32\DLL_Output\Debug和cryptodir\Win32\DLL_Output\Release中的cryptolib.lib链接。
这一步很顺利,但是当尝试将TestApp 构建为分别用于调试或发布的/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$0A@@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$0A@@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$0A@@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$0A@@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。我最初的想法是将所有内容都作为静态库,但我不知道是否可以在该解决方案配置上实现这一点。
帮助表示赞赏。
【问题讨论】:
-
您还必须使用 /MDd 重建 cryptlib。
标签: c++ visual-studio-2012 dll static-libraries crypto++