Linker error: "LNK 2019"

Aug 25, 2010 at 6:19pm
I have looked at some of the other topics regarding this error, but I haven't found any that help my problem.

I'm using Visual C++ 2008 and I've been working on a project for a few days and now I'm getting the following error when building:

CRC32.obj : error LNK2019: unresolved external symbol "void __cdecl utils::cpy_array<char>(char * &,char * &,int)" (??$cpy_array@D@utils@@YAXAAPAD0H@Z) referenced in function "public: __thiscall CRC32::CRC32(char *,int)" (??0CRC32@@QAE@PADH@Z)
1>C:\Documents and Settings\aba\My Documents\Visual Studio 2008\Projects\Encryption\Debug\Encryption.exe : fatal error LNK1120: 1 unresolved externals


I've found that removing the line which calls utils::cpy_array, will remove the error, but - of course - that is not a suitable solution.

I've used #pragma once in every .h-file and even added an extra include guard on the file declaring utils::cpy_array.

I might also add that utils::cpy_array is a template function and that it worked until I created another function, which doesn't interfere with utils::cpy_array at all, called string get_flags(char *input[], char *delims).

If anyone has any idea what is coursing this or just a simple way to get around it, I'd be happy to hear :)
Aug 25, 2010 at 6:24pm
Templatized functions must have their definitions included in the header file, not the cpp file. It could be what's causing your problem.
Aug 25, 2010 at 6:49pm
It removed the problem, but now I get the following:

1>Main.obj : error LNK2005: "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl utils::get_flags(char * * const,char *)" (?get_flags@utils@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAPADPAD@Z) already defined in CRC32.obj
1>C:\Documents and Settings\aba\My Documents\Visual Studio 2008\Projects\Encryption\Debug\Encryption.exe : fatal error LNK1169: one or more multiply defined symbols found
Aug 25, 2010 at 7:21pm
Sounds like there's two definitions for get_flags(); one in Main.cpp, the other in CRC32.cpp. Either that or the include guard is missing from the header file where get_flags() is declared, but you said all of them are guarded.
Aug 25, 2010 at 8:07pm
That was what I read of it as well, but there are no definition of get_flags() in any of those files, only a call from Main.cpp.

However both Main.cpp and CRC32.cpp includes Tools.h (where get_flags() is defined) the guard that I'm using is:

1
2
3
4
5
6
7
8
9
#pragma once

#ifndef __TOOLS__
#define __TOOLS__
.
.
//Declaring and defining get_flags()
.
#endif 


Any idea what might be wrong?
Last edited on Aug 25, 2010 at 8:14pm
Aug 25, 2010 at 8:15pm
Remove the definitions from Tools.h (except the inlined ones) and move them to a Tools.cpp file.
Aug 25, 2010 at 8:16pm
Okay, I got it fixed now :)

All the template functions are defined in the header file as you said.

But what seemed to mess it up was that I also moved a none-template function - guess which :P - so I just moved get_flags() back to the source file again and it works... For now at least.

Thank you for your help.
Aug 25, 2010 at 8:18pm
It's weird though that the templates are to be in the header and the regular ones in the source isn't it?

Anywho, it works.

And thanks again.
Last edited on Aug 25, 2010 at 8:19pm
Aug 25, 2010 at 8:34pm
I find it a bit clumsy too, not to mention it "pollutes" header files. But here's a good explanation of why: http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file

If you're sure only one translation unit will ever use a certain template I don't think there's any technical problems with putting the implementation into a .cpp file, but it's certainly not good practice.
Last edited on Aug 25, 2010 at 8:34pm
Topic archived. No new replies allowed.