Reputation: 18441
I have the following project structure on VS2012 C++:
cryptopp
: As downloaded and build from cryptopp project.
AccessLib
: A static library build using cryptopp functions.
TestApp
: A Win32 console application that uses AccessLib (and cryptolib indirectly)
UserApp
: A Windows interactive application with CLR support (/clr
) that uses AccessLib (and cryptolib indirectly)
Well, my first try was to make this solution work to build my console application and my windows application. BTW, cryptopp
was build in a way described in manuals and this SO link. All tests from cryptopp project are running fine in the build environment.
Here is how I´ve build my project:
Set AccessLib
as being /Mtd
or /MT
for Debug or Release respectively, linking with cryptolib.lib
from cryptodir\Win32\Output\Debug
and cryptodir\Win32\Output\Release
respectively.
Set TestApp
as being also /MTd
or /MT
for Debug or Release respectively, linking to AccessLib.lib
generated from step above.
Fine till now, but when building UserApp
it does not work as TestApp
needs /clr
and that´s incompatible with MTd
or /MT
.
So, here goes my first question: I can´t have a CLR program that links to a static library that has /MTd
or /MT
.... What should I do to build my /clr
program to my static library AccessLib.lib
that access cryptopp
as a static library also ? Should I need to convert everything to DLL project ?
Well, I even tried to convert to use cryptopp as a DLL, that way:
AccessLib
as being /MDd
or /MD
for Debug or Release respectively, linking with cryptolib.lib
from cryptodir\Win32\DLL_Output\Debug
and cryptodir\Win32\DLL_Output\Release
respectively.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:
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 ==========
I did not move to build UserApp
with that configuration.
Help is appreciated to make this whole thing work together. 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.
Help appreciated.
Upvotes: 2
Views: 3314
Reputation: 118
You can not link a library compiled with MT or MTd to a program complied with MD or MDd. They have different CRT library.
You can rebuild cryptopp with MD or MDd
Upvotes: 2
Reputation: 102205
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...
You are mixing and matching runtimes. You should probably change Crypto++ and make it use dynamic runtime linking the the C/C++ runtime library. See Visual Studio | Dynamic Runtime Linking on the Crypto++ wiki.
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.
Yes, this is preferred. It will work, but you need to build the Crypto++ static library using dynamic runtime linking. The project you want is cryptlib
, and its output is found in <crypto++ dir>/Output/{Debug|Release}/{Win32|x64}
. See the previous links.
You should also avoid the FIPS DLL. The DLL project is cryptdll
, and its output is found in <crypto++ dir>/DLL_Output/...
. The DLL is special purpose, and it only provides FIPS algorithms. Its not a general purpose DLL, it lacks most stuff you need, and it causes a lot of pain and misery.
I even go so far as to tell people to completely delete the cryptdll
and dlltest
projects because they cause so much trouble. Also see FIPS DLL on the Crypto++ wiki.
Link errors using cryptopp on VS2012 static library, console application and clr program
This is noteworthy... Crypto++ does not use the /clr
option. You will need to modify the static library project settings and add it.
The static library's project is called cryptlib
. You will need to do it for Win32 Debug, Win32 Release, x64 Debug and x64 Release.
Upvotes: 1