error LNK2005 when c++ lambdas used with /Yu flag in vs2012 - c++

I have the following function in one of my utility header files.
template<typename T>
static void rtrim(std::basic_string<T, std::char_traits<T>, std::allocator<T>> &t)
{
t.erase(find_if(t.rbegin(), t.rend(),
[](T& c)->bool{ return !isspace(c); }).base(), t.end());
}
I am building the code with Visual Studio 2012 with pre-compiled headers on (/Yu). The build fails with the following error.
1>stdafx.obj : error LNK2005: "public: void __cdecl
::operator()(class
std::basic_string,class
std::allocator > const &)const "
(??R##QEBAXAEBV?$basic_string#_WU?$char_traits#_W#std##V?$allocator#_W#2##std###Z)
already defined in
If I remove /Yu flag, it builds fine. Does it mean lambdas cannot be used with precompiled headers? Is there a work around?

Related

Add External C Library in a Visual C++ Application - "Error LNK2028" & "Error LNK2019"

I am working on a C++ Windows Form Application in Visual Studio 2019.
I want to use some functions of the external library EDFlib. EDFlib is a programming library for C/C++ which consists of only two files (.c and .h).
Here, a simple code that writes data in an EDF file when I click on a button:
#include "edflib.h"
// [...]
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
double buf[200];
for (int i = 0; i < 200; i++)
buf[i] = i;
int hdl;
hdl = edfopen_file_writeonly("test.edf", EDFLIB_FILETYPE_EDFPLUS, 1);
// [...]
edfwrite_physical_samples(hdl, buf);
edfclose_file(hdl);
}
// [...]
I have the 2 following errors:
Erreur LNK2028 jeton non résolu (0A000038) "extern "C" int __cdecl edfopen_file_writeonly(char const *,int,int)" (?edfopen_file_writeonly##$$J0YAHPBDHH#Z) référencé dans la fonction "private: void __clrcall TestEDF::MyForm::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click#MyForm#TestEDF##$$FA$AAMXP$AAVObject#System##P$AAVEventArgs#4##Z)
&
Erreur LNK2019 symbole externe non résolu "extern "C" int __cdecl edfopen_file_writeonly(char const *,int,int)" (?edfopen_file_writeonly##$$J0YAHPBDHH#Z) référencé dans la fonction "private: void __clrcall TestEDF::MyForm::button1_Click(class System::Object ^,class System::EventArgs ^)" (?button1_Click#MyForm#TestEDF##$$FA$AAMXP$AAVObject#System##P$AAVEventArgs#4##Z)
I tried to read documentation about these errors.
But I am not an C/C++ expert. I don't know what to do. I need some help.
Thanks.
I am guessing the errors state that you have unresolved symbols,
it means that you are calling functions that you have a declaration for (from the #include "edflib.h") that the linker tries to find during the build process but have no definition.
it seems like you just included the header of the library, but you need to also link with it.
I don't know what IDE you use but you should look up how to link libraries to your projects in C++.
there is a lot of information about creating and linking libraries online that should help you solve this issue.
You Should Give Extern "C" Method and Add the Library into It, Check
https://isocpp.org/wiki/faq/mixing-c-and-cpp
You Cannot Externally Add C Libraries in C++

VS2015: LNK2019 error when linking with Muiload.lib

I'm experimenting the next error when including muiload.h and linking with muiload.lib and calling LoadMUILibrary in Visual Studio 2015:
Muiload.lib(muiload.obj) : error LNK2019: unresolved external symbol
__vsnwprintf referenced in function "long __stdcall StringVPrintfWorkerW(unsigned short *,unsigned int,unsigned int
*,unsigned short const *,char *)" (?StringVPrintfWorkerW##YGJPAGIPAIPBGPAD#Z)
Maybe something wrong in muiload.lib?
Solved adding the additional library legacy_stdio_definitions.lib to the linker input as explained in https://social.msdn.microsoft.com/Forums/en-US/5150eeec-4427-440f-ab19-aecb26113d31/updated-to-vs-2015-and-now-get-unresolved-external-errors?forum=vcgeneral
An alternative to linking against legacy_stdio_definitions.lib is to redefine these function signatures to match their deprecated style:
int (WINAPIV * __vsnprintf)(char *, size_t, const char*, va_list) = _vsnprintf;
int (WINAPIV * __vsnwprintf)(wchar_t *, size_t, const wchar_t*, va_list) = _vsnwprintf;
One benefit of this is that it avoids other possible linker definition issues caused by including the legacy library.
Note that this should be defined in a compiler unit (.cpp) rather than in a header file.

Getting error LNK2005 in Visual Studio 2013 on std::string methods and operators

I have a Qt-based project that I have been building and using Visual Studio 2008 for about 5 years. I build and use both 'Debug' and 'Release' build configurations.
I'm migrating to VS2013 and now I'm getting some rather strange LNK2005 errors on std::string methods and operators.
The code base is broken into two libraries and a bunch of UI directories. In Debug build configuration the two libraries are built into DLLs and then must be specified in the PATH when running one of the UIs. In Release mode everything is compiled statically into a single executable. Works great.
The two libraries are 'model' and 'engine'. The 'model' is built first and the 'engine' is then built. The 'engine' uses the 'model' (library).
When the 'engine' is linked, I get a bunch of the following errors, all dealing with std::string:
1>model.lib(model.dll) : error LNK2005: "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
& __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::operator=(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)"
(??4?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##QAEAAV01#ABV01##Z)
already defined in NamedObject.obj
1>model.lib(model.dll) : error LNK2005: "public:
int __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::compare(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)const "
(?compare#?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##QBEHABV12##Z)
already defined in NamedObject.obj
The first looks like the 'std::string::operator=(const std::string &)' operator. The 'NamedObect' class is in 'engine' and does NOT override 'std::string::operator=()'. In fact, 'NamedObject' is basically a simple wrapper around a 'std::string' attribute, an accessor and a 'bool operator== (const NamedObject &)' method, that looks like the following:
bool
NamedObject::operator== (const NamedObject &v)
{ return (name == v.name); }
There are many other LNK2005 errors like this, but this one is fairly isolated to a small class.
Things I've checked/verified:
I'm compiling and linking with consistent '/Mxx' compiler options (/MDd) in this case.
The '-Zc:wchar_t' option is specified in both the Makefiles for the 'model' and 'engine'.
Both libraries link with '/NOLOGO /DYNAMICBASE /NXCOMPAT /DEBUG /NODEFAULTLIB:LIBCMT /NODEFAULTLIB:LIBCPMT /NODEFAULTLIB:LIBCMTD /NODEFAULTLIB:LIBCPMTD /NODEFAULTLIB:MSVCRT /NODEFAULTLIB:MSVCPRT /DLL'
A 'dumpbin /dependencies' on the various object files reveal '/DEFAULTLIB:msvcprtd /DEFAULTLIB:MSVCRTD /DEFAULTLIB:OLDNAMES'.
I. Am. Stuck.
EDIT. More details. I did a dumpbin /all model.dll on both versions (VS2008 and VS2013) and found that, indeed, the VS2013 version included std::string implementations: ??4?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##QAEAAV01#PBD#Z (public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > & __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::operator=(char const *))
but the VS2008 version did not.
EDIT 2 Well, I decided to give this the 'ol college try..... I've isolated this to just a few small classes (and yes, everything is compiled with the same version of the compiler, same VS solution, etc., etc....).
Here's what I have for the declaration of a simple 'model' class. I'll explain later about some stuff. You can sort of figger out what the implementation of the methods are.....
# pragma once
# if defined(WIN32) && defined(BUILD_DLL)
# if defined(MODEL_EXPORT_API) // inside DLL
# define MODEL_EXPORTAPI __declspec(dllexport)
# define MODEL_EXPIMP_TEMPLATE
# else // outside DLL
# define MODEL_EXPORTAPI __declspec(dllimport)
# define MODEL_EXPIMP_TEMPLATE extern
# endif
# else
# define MODEL_EXPORTAPI
# endif
# include <string>
# if defined (WIN32)
MODEL_EXPIMP_TEMPLATE template class MODEL_EXPORTAPI std::basic_string<char, std::char_traits<char>, std::allocator<char> >;
# endif
namespace model { namespace exceptions {
class MODEL_EXPORTAPI FlowException {
public:
FlowException(const std::string & m);
virtual ~FlowException();
virtual const char * what() const;
private:
// Copy constructor and assignment operator are private and
// unimplemented.
FlowException(const FlowException &);
FlowException & operator=(const FlowException &);
std::string _msg;
};
} }
For 'engine' classes. This one is similar to the 'model' class above. Again, you can figger out what the implementation would be...
# pragma once
# include <string>
# if defined(WIN32) && defined(BUILD_DLL)
# if defined(FLOWENGINE_EXPORT_API) // inside DLL
# define FLOWENGINE_EXPORTAPI __declspec(dllexport)
# define FLOWENGINE_EXPIMP_TEMPLATE
# else // outside DLL
# define FLOWENGINE_EXPORTAPI __declspec(dllimport)
# define FLOWENGINE_EXPIMP_TEMPLATE extern
# endif
# else
# define FLOWENGINE_EXPORTAPI
# endif
namespace flowEngine { namespace core {
class NamedObject {
public:
NamedObject(const std::string & n);
virtual ~NamedObject();
bool operator== (const NamedObject & v) const;
const char * getName() const;
private:
// Copy constructor and assignment operator are private and
// unimplemented.
NamedObject(const NamedObject &);
NamedObject & operator=(const NamedObject &);
std::string _name;
};
} }
Now for the tests.
If I don't have that 'MODEL_EXPIMP_TEMPLATE template class...' line in the 'model exception' class, then I get 'warning C4251: 'model::exceptions::FlowException::_msg' : class 'std::basic_string,std::allocator>' needs to have dll-interface to be used by clients of class 'model::exceptions::FlowException'' on each reference of that header file and this example links.
If I 'include' that 'exception' class in the model into a class in the engine, and w/o that 'MODEL_EXPIMP_TEMPLATE template class...' line this example works (both libraries link).
If I include that 'exception' class in the model into a class in the engine WITH THE ''MODEL_EXPIMP_TEMPLATE template class...' line in the exception class, then this example fails when the engine library is linked with: '1>model.lib(model.dll) : error LNK2005: "public: __thiscall std::basic_string,class std::allocator >::basic_string,class std::allocator >(char const *)" (??0?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##QAE#PBD#Z) already defined in NamedObject.obj'
Now what? In one case the compiler is telling to fix the code and when I do links fail....

Why am I getting this error ? "unresolved external symbol" [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 9 years ago.
This is the error I have been getting the whole time and I've been trying to figure out how to fix it but have failed. I am asking if anyone can point me to the right direction.
WorldServer fatal error LNK1120: 2 unresolved externals
WorldServer error LNK2019: unresolved external symbol "public: class CItemElem * __thiscall CLinkedItemMgr::GetLinkedItem(unsigned long)" (?GetLinkedItem#CLinkedItemMgr##QAEPAVCItemElem##K#Z) referenced in function "private: void __thiscall CDPSrvr::OnLinkedItem(class CAr &,unsigned long,unsigned long,unsigned char *,unsigned long)" (?OnLinkedItem#CDPSrvr##AAEXAAVCAr##KKPAEK#Z)
WorldServer error LNK2019: unresolved external symbol "public: int __thiscall CLinkedItemMgr::AddLinkedItem(class CItemElem *)" (?AddLinkedItem#CLinkedItemMgr##QAEHPAVCItemElem###Z) referenced in function "private: void __thiscall CDPSrvr::OnLinkedItem(class CAr &,unsigned long,unsigned long,unsigned char *,unsigned long)" (?OnLinkedItem#CDPSrvr##AAEXAAVCAr##KKPAEK#Z)
This is the .h
#ifndef __ITEM_LINK__H
#define __ITEM_LINK__H
class CLinkedItemMgr
{
private:
CLinkedItemMgr(){ m_dwLinkedItemCount = 0;};
~CLinkedItemMgr(){};
DWORD m_dwLinkedItemCount;
public:
map<DWORD,CItemElem*> m_mapLinkedItems;
static CLinkedItemMgr *GetInstance()
{
static CLinkedItemMgr instance;
return &instance;
}
int AddLinkedItem(CItemElem *pItem);
CItemElem *GetLinkedItem(DWORD dwIndex);
};
#endif
this is the .cpp
#include "stdafx.h"
#include "ItemLink.h"
int CLinkedItemMgr::AddLinkedItem(CItemElem *pItem)
{
if(!pItem)
return 0;
m_mapLinkedItems.insert(make_pair<DWORD,CItemElem*>(++m_dwLinkedItemCount,pItem));
return m_dwLinkedItemCount;
}
CItemElem *CLinkedItemMgr::GetLinkedItem(DWORD dwIndex)
{
map<DWORD,CItemElem*>::iterator it = m_mapLinkedItems.find(dwIndex);
if(it == m_mapLinkedItems.end())
return FALSE;
return it->second;
}
Your problem is in the cpp here.
#ifdef __ITEM_LINK
#include "ItemLink.h"
#ifdef __ITEM_LINK means "only process the code below if __ITEM_LINK is defined"
And in your case, it is not defined. It only gets defined when "ItemLink.h" is included, and "ItemLink.h" only gets included if it's already defined. You've prevented either from happening first.
Remove the #ifdef line.
It looks like a linking problem.
The compiler knows your class has a function called GetLinkedItem but can't find any definition of that function anywhere. Are you linking properly when compiling your executable?
I bet stopping the compiler before linking doesn't trigger any error.
(e.g. g++ -c ItemLink.cpp).
i'm going to ask the help of someone who's accustomed to visual studio to elaborate more :D
anyway, compiling requires three major steps:
1) applying preprocessor directives, parsing the source code, looking for syntax errors and the like
2) creating an object file from source code (something half-way between source code and executable)
3) linking all the object files making up your project in one executable
your compiling chain fails at the third step.
the compiler expects a certain function to be defined in some .cpp (that has become an object file at step 2 of compiling chain) but can't find it anywhere.
and it can't find it because of that #ifdef in the .cpp file, which tells the preprocessor NOT TO INCLUDE your definitions, since __ITEM_LINK is not defined
i see you changed the .cpp in your question by the way

Unresolved externals using C++ lambdas [duplicate]

This question already has answers here:
Why do I get "unresolved external symbol" errors when using templates? [duplicate]
(3 answers)
Why can templates only be implemented in the header file?
(17 answers)
Closed 9 years ago.
I am getting unresolved externals compile error with following code snippet.
acquire_gray(identity, []{});
samething happens when I try to use auto
auto acquire_callback = [](LPBITMAPINFOHEADER pbi, HANDLE hdib)
{
printf("Callback\n");
};
acquire_gray("", acquire_callback );
but when I pass in null it compiles
acquire_gray(identity, NULL);
This is structure of my program
driver.cpp
#include "bridge.h"
void TB_AcquireImagesStart(HANDLE hNamedPipe, const TB_Message request)
{
acquire_gray("", []{});
}
bridge.h
template<typename T>
void acquire_gray(const string_t& identity, T& callback);
bridge.cpp
template<typename T>
void acquire_gray(const string_t& identity, T& callback)
{
callback();
}
So the two exceptions that I am getting are
Error 12 error LNK1120: 1 unresolved externals
Error 11 error LNK2019: unresolved external symbol "void __cdecl acquire_gray<class <lambda_e125ff607fe0339bba6077ce9c14d586> >(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class <lambda_e125ff607fe0339bba6077ce9c14d586> &)" (??$acquire_gray#V<lambda_e125ff607fe0339bba6077ce9c14d586>####YAXABV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##AAV<lambda_e125ff607fe0339bba6077ce9c14d586>###Z) referenced in function "void __cdecl TB_AcquireImagesStart(void *,class TB_Message)" (?TB_AcquireImagesStart##YAXPAXVTB_Message###Z)
So my question is what is wrong with my code, and how can I fix this, and why is auto not detecting my lambda type.
You can't put template definitions in .cpp (well you can, but it only makes sense if you're using them in that compilation unit). After compilation, only template instanciations exist.
This is just a common pitfall when using templates. You cannot (or at least should not) separate a template into header (.hpp) and source (.cpp) files. See here for details.