Mendes
Mendes

Reputation: 18441

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

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:

Fine till now, but when building UserAppit does not work as TestApp needs /clr and that´s incompatible with MTdor /MT.

So, here goes my first question: I can´t have a CLR program that links to a static library that has /MTdor /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:

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

Answers (2)

owent
owent

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

jww
jww

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

Related Questions