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.
Related
So, usually when you see an Unresolved External Symbol error, the linker at least tells you what function the reference is in, i.e.
unresolved external symbol "class1::function1" **referenced in function "class2::function2"**
But what do you do when you only get the first half? i.e.
unresolved external symbol "class1::function1"
I know where "class1::function1" is defined, and I am deliberately not including it. So just including the file containing the definition won't help. The include is ifdef'd out, along with all references to symbols contained in the file. What I need is a way to locate the reference to this deliberately non-included symbol so that I can get rid of it. Searches for the name of the symbol reveal only things which I have already ifdef'd out.
If it's a virtual function then it's referenced from the vtable, which in turn is referenced from each constructor (or each place where a constructor is inlined).
If you're using instances of the class I think your best bet is to remove the virtual keyword. Otherwise you must provide a definition, even if only a stub.
(The language standard handles this by considering any virtual function as always used, so a definition is required.)
I'm not sure why that happens, but easy way to determine source of problem is to comment out all declarations of class1::function1, and rebuild the project - compiler will complain whenever class1::function1 is called on compile stage instead of linking.
This turns out to have been a combination of a mistake on my part, and a non-helpful error message. One of the classes was missing a member of it's inheritance chain.
Personally I would have expected this to result in a compiler error ("Extending Undefined Base Class" or something similar), but instead I got linker errors for the virtual functions in said base class (despite that class not being included). But because no functions were actually referencing them, the linker could not provide a "referenced in" section for the error message. I still don't entirely understand why this set of problems with the code gave that set of error messages, but I was able to fix it.
Thank you Alan for your input, it got me looking in the correct direction. I would upvote you, but having joined immediately before posting the question, I lack the reputation score to do so.
I have two modules, each with own class and with own object. Each module is compiled to a DLL. I want to make a "cross-DLL" method call, having pointer to the object of another class, but linker doesn't allow to do this (MSVC++ 2008).
More specifically:
there is calledModule.cpp, that has calledClass, and object of this class (calledObject); class has calledMethod, which I want to call; module is compiled to DLL and becomes (surprise!) calledLib.dll.
there is callingModule.cpp, that has callingClass; among other things, the class has the attribute, which is a pointer to the calledObject; module is compiled to DLL callingLib.dll; the pointer on calledObject is set in the constructor.
I'm able to compile the whole code. The trouble comes when the linker starts. I'm getting the following:
moduleCalling.obj : error LNK2001: unresolved external symbol "public: void __thiscall classCalled::methodCalled ..."
I don't use any declspec things, so nothing is exported from the calledLib.dll.
The method that I'm calling (methodCalled) is present in the implementation, its prototype is correctly declared in header. The classCalled is a "basic" class, not inherited from anything.
Moreover, the whole project compiles and working correctly, when I declare methodCalled as a virtual...
I have troubles understanding, why I can't call the method of the object in a "normal" way from another DLL? Why declaring it as a "virtual" helps? Anyone knows? I have some guesses, but expert answer will help a lot to understand this stuff.
P.S.: I'm using MSVC++ 2008.
Thanks!
Update: adding code snippet, which reflects, how the code looks like.
// part of calledLib.dll
// moduleCalled.h
class classCalled {
public:
int methodCalled() { return 1 };
};
// ---------------------------------------------------------------
// part of callingLib.dll
// moduleCalling.h
#include "moduleCalled.h"
class classCalling {
public:
classCalled* ref;
void justSomeMethod();
};
// ---------------------
// moduleCalling.cpp
#include "moduleCalling.h"
void classCalling::justSomeMethod() {
ref = new classCalled();
int a = ref->methodCalled(); // <--- this is not allowed by linker,
// unless methodCalled is made virtual.
}
Linker links pieces of code from various modules. If you have a call from one module to another, linker has to know in which other module the function you're invoking is implemented and substitute the call by the real address. This is a very rough picture, but it's enough to understand what is going on.
In your case the linker has to know that your function is located in calledLib.dll. Therefore you have to link with something that refers to calledLib.dll. This something is called an import library. It's name should be calledLib.lib. In order to generate it you either should write a .def file, but it's difficult for class methods, since class methods names used by linker look very different from what they look like in your C++ code. Or you can use declspecs. It will generate the proper calledLib.lib, which you will have to link with your callingLib.dll.
I'm somewhat new at C++ (I normally work in C#, but right now I'm working on a somewhat cross-platform project), so I'm not really used to all of its concepts and exactly how compiling/linking works. So, naturally, I'm not quite sure why I'm getting this error. I've researched the error a bit, and it seems a problem people commonly get when they don't link a library or declare a function in a header file but never define it outside of that. My error, oddly, is not a result of either. The exact error text is this:
"Error 1 error LNK2001: unresolved external symbol "public: __thiscall ld22::QuadNode<class ld22::DrawableObject>::QuadNode<class ld22::DrawableObject>(class sf::Rect<float>)" (??0?$QuadNode#VDrawableObject#ld22###ld22##QAE#V?$Rect#M#sf###Z) C:\Users\Nick\Documents\Visual Studio 2010\Projects\GDCSFMLTest\GDCSFMLTest\main.obj"
To me, it seems like it's trying to tell me that I never made an implementation of the file. However, I have. main.cpp, the file that compiles into main.obj and gives the error, includes Quadtree.h, which declares the function (technically, constructor) with the line QuadNode(sf::FloatRect);, and in the file Quadtree.cpp I include Quadtree.h and define the constructor as follows:
template<class T>
ld22::QuadNode<T>::QuadNode(sf::FloatRect bounds)
{
Bounds = bounds;
}
Please excuse any bad coding practices and whatnot, as I said, I'm fairly new to C++ and I'm still trying to figure things out. Any help is appreciated (especially if I made a stupid or beginners error somewhere, which I kinda feel I did), and if you need more info I'd be glad to provide it.
In C++, templated classes have to be defined in header files. This is because unlike generics in C# where they keep track of the <T> type at runtime, a new class is actually generated by the compiler for each <T> you use it with. The compiler has no way to actually compile a templated form of the class, and then link-in the type information. The way I see it, templates in C++ are really a form of source-code transformation that happens before the compilation stage.
See this question for more information as to why:
Why can templates only be implemented in the header file?
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
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.