Can Somebody tell me what does the following error implies?
Error 2 error LNK2019: unresolved
external symbol "public: class
TLst & __thiscall
TLst::operator=(class
TLst const &)"
(??4?$TLst#VTInt####QAEAAV0#ABV0##Z)
referenced in function "public: void
__thiscall TPair >::GetVal(class TInt
&,class TLst &)const "
(?GetVal#?$TPair#VTInt##V?$TLst#VTInt######QBEXAAVTInt##AAV?$TLst#VTInt#####Z) randomgraph.obj randomgraph
In general, it means that the linker sees a reference to a symbol, but it can't find it anywhere - often due to a missing library or object file.
In this case this happened because you implemented your templated class'es member functions in a .cpp file - they should be implemented in the header.
A template class is a template not a class. When the compiler see you using e.g. vector<int> f; it creates a new class vector<int> from the template vector. In order to create e.g. vector<int>::size() it needs to see the implementation of size() at the point where the template is instantiated - and it can't do that if the implementation of size() isn't in the header file.
You can get around this by explicitly instantiating vector for int - Then the compiler will see the explicit instantiation when it compiles the cpp file. This defeats the purpose of having a template - it'd only be usable for the types you predefine with explicit instantiation. So, short story, always fully implement templates in header files.
Unresolved external symbol means that there's a reference that the linker can't find. It's usually caused by forgetting to add an object file or library to the link step. (Including the header file for a class isn't enough - you also have to add the implementation code.)
This problem is solved. In the template class TLst, the function
TLst TLst::operator=(const TLst&);
was declared but it was not defined.
I had to define the function in my .cpp file. I could have defined it in my header file as well.
Thanks for the replies.
Somnath
Related
I want to parameterize the return value of a function to match the return value of a function pointer I pass it. I've only dealt with java generics before, so there's a good chance I'm completely missing something here.
the function looks like:
<in header>
template <typename T> static T getItems(const char* xpath, T (*getThings)(xpath_node_set*));
<in body>
template <typename T>
T XMLAdapter::getItems(const char* cpath, T(*getThings)(xpath_node_set*)){
return getThings(head.select_nodes(path));
}
and the function i'm passing into it looks like this:
size_t handler(xpath_node_set* in){
return in->size();
}
And the error i'm getting is:
Error 1 error LNK2019: unresolved external symbol \
"public: static unsigned int __cdecl XMLAdapter::getItems<unsigned int>(char const *,unsigned int (__cdecl*)(class pugi::xpath_node_set *))" (??$getItems#I#XMLAdapter##SAIPBDP6AIPAVxpath_node_set#pugi###Z#Z) \
referenced in function _wmain C:\Users\Adam\SkyDrive\Documents\proj\ray\ray\ray.obj ray
What gives?
remove the static from the prototype, it makes your function file local (i.e. invisible to other TUs).
Generally the function template definition should appear in the header, not a separate .cpp file.
Template functions need to be fully implemented (not just declared) in the header or you'll hit linker errors like this, if your caller and the template function are not in the same .cpp file.
Think about it this way:
When you run the compiler on your code, you're actually compiling a separate .obj file for every single .cpp file. From the point of view of the compiler, these are completely independent black boxes. Every .cpp file could be compiled in parallel, and there are zero dependencies between them. The only dependcies are function declarations (specified in headers) which say "yeah, yeah...someone else is implementing this, let the linker complain if it can't find it."
When you have a template function, what you're really making is a recipe for how to make a function. If you have Foo<T> and you want to call it with int's and with string's, there are literally two generated functions that are completely symbolically different in your final binary: Foo<int> and Foo<string>.
That said, if you have your implementation of your template function in a separate .cpp file from someone who is trying to call a specialized version of it, they have no way to "cook" a new version of that function with whatever template arguments they are supplying. All they have is a header that says "Foo<T> is a function someone else implemented" to appease the linker. But your TemplateImplementation.cpp has no way of knowing that it should have generated a Foo<int> and a Foo<string>.
This is why you'll always see template libraries shipped as header-only libraries. No one could ship you a lib with compiled template functions if they wanted to, because they can't generate the functions until you have called specific versions.
I am working on a simple top down shooter and wanted to move my ships to a separate ShipManager class, where I can manage all of them from a single location. However, upon starting this I get a linker error on my playerShip:
error LNK2001: unresolved external symbol "public: static class Ship * ShipManager::playerShip"
ShipManager.h looks like this:
class Ship;
class ShipManager
{
public:
static Ship* playerShip;
};
I have nothing in the ShipManager .cpp yet. What am I missing? The only other place I use this code is in my game class where I am actually calling ShipManager::playerShip, and I don't get any errors there.
I include "ShipManager.h" in my game.cpp, so it should find it right? I have a feeling I'm forgetting something simple in this class.
Static members have to be defined somewhere. You are declaring playerShip, but not defining it. You need to add somewhere, necessarily and only one cpp file:
Ship* ShipManager::playerShip;
You only declared the static member, you also need to define it in (only)one of your cpp files:
Ship* ShipManager::playerShip;
Good Read:
What is the difference between a definition and a declaration?
I asked the same question yesterday and the answer was not applicable.
https://stackoverflow.com/questions/6194578/breaking-up-class-functions-into-multiple-cpp-files
If I go into the class header, right click on the function and click "Go to Definition" and it takes me right to my function in my other .CPP file. It sees it, can link to it and still I get errors that indicate I cannot see it.
Anyone have any suggestions? I'll try anything.
Here is the error again.
zdll.lib(d000050.o) : warning LNK4078: multiple '.text' sections found with different attributes (E0300020)
WLD.obj : error LNK2019: unresolved external symbol "public: void __thiscall WLD::fragment_03(unsigned char *,int)" (?fragment_03#WLD##QAEXPAEH#Z) referenced in function "public: bool __thiscall WLD::init(unsigned char *)" (?init#WLD##QAE_NPAE#Z)
Edit: Also, I am using MSVC++. Should I try creating a new solution and importing the files? May help as I feel I am out of options...
Edit: Here is the code:
#include "WLD.h"
inline void WLD::fragment_03(uchar* location, int frag_num)
{
// Read the struct into memory and create a temporary pointer
struct_frag03 temp03;
memcpy(&temp03, location, sizeof(struct_frag03));
uchar* temp_p = location;
// Advance the pointer to the encoded bytes (filename)
temp_p += sizeof(long) + sizeof(short);
// Grab the encoded filename and decode it
uchar* f_filename = new uchar [sizeof(temp03.nameLen + 1)];
memcpy(f_filename, temp_p, temp03.nameLen + 1);
decode(f_filename, temp03.nameLen);
// Add the details about this bitmap to the array
bmp_array[current_bmp].filename = f_filename;
bmp_array[current_bmp].nameLength = temp03.nameLen;
bmp_array[current_bmp].reference03 = frag_num;
// 0x03 Debug
//errorLog.OutputSuccess("0x03 Filename: %s", bmp_array[current_bmp].filename);
//errorLog.OutputSuccess("0x03 Name length: %i",bmp_array[current_bmp].nameLength);
//errorLog.OutputSuccess("0x03 Reference: %i", bmp_array[current_bmp].reference03);
// Add the bitmap to the count
current_bmp++;
}
And here is where the code is called in the WLD class:
case 0x03:
fragment_03(wld + file_pos + sizeof(struct_wld_basic_frag), i);
break;
Here is the header file declaration: in (WLD.h):
public:
inline void fragment_03(uchar* location, int frag_num);
inline means that the function effectively has internal linkage (that is, it must exist inside the translation unit where it is used). Either move the definition of the function into the header, or remove inline.
(inline for modern compilers really means "use internal linkage" -- compilers will inline where it makes sense to by themselves, and they typically make better decisions than humans)
EDIT: Technically speaking, the language the standard uses here says that inline functions have external linkage; however, it also says An inline function shall be defined in every translation unit in which it is used. in section 3.2 paragraph #3 of the standard, and also There can be more than one definition of a ... inline function
with external linkage (7.1.2) ... Given such an entity named D defined in more than one translation unit ... each definition of D shall consist of the same sequence of tokens in paragraph 5. So while technically speaking the name you declared inline is accessible from outside a given translation unit, to do so is to cause undefined behavior from C++.
This has nothing to do with includes. What you have there is a linker error. Includes are all about compilation, which requires the declarations of identifiers referred to.
The error you have means that the linker can't find the definition of a function in any of the object files passed to it which is called by one or more of them. (See this answer for what's a declaration and what's a definition and what they are needed for.)
You need to pass to the linker the object files created from compiling all of your .cpp files. If you're using some sort of an IDE, it should do this for you if you add all .cpp files to your project. If you're using a makefile, list all .cpp files as dependencies of your target. If you compile by invoking the compiler manually (which then calls the linker), pass all .cpp files to it in the same invocation.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is an undefined reference/unresolved external symbol error and how do I fix it?
I am terrible at reading c++ errors, but obviously Unresolved External Symbol means the function I am using isn't defined. The error I am getting is...
1>WorldState.obj : error LNK2001: unresolved external symbol "public: class Brutal::GameObject * __thiscall Brutal::GameObjectManager::createObject<class Player>(class Ogre::Vector3,class Ogre::Quaternion,class Brutal::PropertyList,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??$createObject#VPlayer###GameObjectManager#Brutal##QAEPAVGameObject#1#VVector3#Ogre##VQuaternion#4#VPropertyList#1#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z)
1>C:\Users\Brett\Desktop\Factions Online\build\release\client\client.exe : fatal error LNK1120: 1 unresolved externals
This doesn't make any sense as createObject is defined and even comes up appropriately in MSVC when I right click it and click "go to definition"
My code which calls it is...
Brutal::GameObjectManager::getSingletonPtr()->createObject<Player>(Ogre::Vector3::ZERO, Ogre::Quaternion::IDENTITY);
So am I missing something silly?
Since you are using a template function, it's definition has to be visible when you call it. Therefore, because this is a member function, it has to be implemented in the header where you declared it.
Given that it is a template, have you put the implementation in a different file from the header? (You can do this for specific classes you decide to declare you have a template implementation for, known as instantiation).
I am going to extend my previous post as I can put in coding suggestions here more easily than in a comment.
You have a template function called createObject. You might consider "refactoring" this to use a class because it is easier to single this out.
This is sample code so fill in the detail to make it work for your exact example.
class GamePlayerManager
{
public:
// all the other stuff
template< typename T > createObject(/*params */)
{
// implement inline
res = GameObjectFactory<T>::create(/* whatever parameters */);
}
};
I have now singled out object creation into its own class called GameObjectFactory. At some point where Player is visible you can instantiate this template whilst hiding its create() method.
template class GameObjectFactory<Player>;
This is good enough for the compiler to know it needs to look in the implementation for the implementation of this class's functions (it promotes it into a "real" class so you can put the implementation into its .cpp file). Note that this is an instantiation, not a specialisation, so your template GameObjectFactory could still implement whatever functions you want to inline and you would not have to redefine them for your class. This is a good way to "reuse" the common code whilst allowing you to specialise on some of the detail.
It looks like you're not linking to the associated library. You've got the header included, so the compiler isn't complaining, but the linker doesn't know what you're talking about.
Is createObject taking default arguments or is it overloaded ?
If so, are you defining all versions of that function?
In the error message, its showing more parameters for function than in the call.
And If functions is defined in some other library, you have to link it with your application by giving that library as input to Linker in Project settings.
Howdy. I am working on a C++ assignment for my class. I am almost done but can't seem to figure out these errors:
error LNK2001: unresolved external symbol "public: virtual void __thiscall HasQuarterState::dispense(void)const " (?dispense#HasQuarterState##UBEXXZ) gumball.obj Gumball
error LNK2001: unresolved external symbol "public: virtual void __thiscall SoldState::turnCrank(void)const " (?turnCrank#SoldState##UBEXXZ) gumball.obj Gumball
fatal error LNK1120: 2 unresolved externals C:\School Work\CS 492\Gumball\Debug\Gumball.exe Gumball
I went to MSDN and looked up LNK2001 error, but was provided with an overwhelming amount of info, and am afraid I can't figure out what is wrong given my limited experience with C++ from looking at the MSDN page.
But I do believe that the problems come from the way I have structured my program. My teacher said we may use one .cpp file if we wanted too, but I guess in the end I didn't know enough about Visual Studios/C++ to make this work. Ultimately I ran into some other problems that I had to solve that came from using one .cpp file.
The code/file in question is here: http://codepad.org/LpBeJT2Y
Its a big ole mess but this is what I have done:
Declare a class named GumballMachine (no definition)
Define a class named State (which in turn has a pointer to a GumballMachine)
Defined several other state classes which inherit from State
Define class GumballMachine
Defined several functions that were excluded from the original definitions of the other state classes. This is because these functions relied on defined functions of GumbballMachine and wouldn't work until the GumballMachine functions were defined.
void main()
As far as I can tell (with my limited knowledge of VS/C++), the code looks to be fine. Maybe there is something someone with more experience would catch. Any pointers on how to knock out this problem?
Thanks for the help.
You've declared dispense in HasQuarterState but have not defined it. The function has no body. Likewise with turnCrank in SoldState.
In class SoldState, turnCrank is not defined. Change this:
void turnCrank() const;
To this:
void turnCrank() const { cout << "some implementation" << endl; }
and similarly for the other function.