Can Someone explain to me how to read MSVC linkage errors in general.
An example is one I have just hit which I know means that somewhere in my code I am attempting to link something dynamically that isn't there.
What I would like to understand is how to read the error message properly so I can work out exactly which module I have left a dllimport on in.
Error LNK2019 unresolved external symbol "__declspec(dllimport) public: enum SILLY::PixelFormat __cdecl SILLY::Image::getSourcePixelFormat(void)const " (__imp_?getSourcePixelFormat#Image#SILLY##QEBA?AW4PixelFormat#2#XZ) referenced in function "public: virtual class CEGUI::Texture * __cdecl CEGUI::SILLYImageCodec::load(class CEGUI::RawDataContainer const &,class CEGUI::Texture *)" (?load#SILLYImageCodec#CEGUI##UEAAPEAVTexture#2#AEBVRawDataContainer#2#PEAV32##Z) helloworldui C:\Users\XXXXXX\Documents\Audio Development\evil-sounds\build\helloworldui\cegui64sd.lib(ImageCodec.cpp.obj) 1
I think it means that CEGUI::SILLYImageCodec::load is trying to load SILLY:Image::getSourcePixelFormat as a dll when I want it to load a static library.
The load#SILLYImageCodec#CEGUI##UEAAPEAVTexture#2#AEBVRawDataContainer#2#PEAV32##Z bit is throwing me off - it seems backwards.
It means the function SILLY::Image::getSourcePixelFormat called (or otherwise referenced) in the function CEGUI::SILLYImageCodec::load cannot be found by the linker.
The error has little to do with the static vs. import library, it can't be found in any library it has looked in. If it can't be found the linker will produce the same error irrespective of where you intended the function to be. You get the error because you have probably not supplied the linker with the library you want it to use (from what you say, this is the likely error, but it could be caused by a whole host of reasons; see here for more).
The name mangling can be cumbersome, unless you want to write a name demangler, you can generally ignore it (look for the pretty print names instead).
The bit with all the '#' signs is the mangled name. You can generally ignore this as the linker has already demangled it for you. It looks like the dllimport is attached to the SILLY::Image class, probably in the form of a macro between 'class' and the class name.
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.
Most of the people who work on UNIX will face this irritating error often.
and some times it will take less time to solve and sometimes it will take hell lot of time.
Even i faced this regularly and i need some good document or an article regarding the specific error in c/c++
what are all the cases where there might be Symbol not found/Undefined Symbol error.
Could anybody help me to know what are all those cases?
The error is not related to UNIX/Windows/any other OS, but rather to the languages themselves. It is actually rather simple to diagnose with the information that compilers provide. Usually they will tell you what symbol is missing and sometimes where it is being used. The main reasons for a symbol to be missing are:
You have declared but never defined it
You have defined it, but did not add the compiled symbol (object file/library) to the linker
It is external and you forgot to link the library, or you are linking an invalid version, or in the wrong order.
The first one is a little trickier if you intended to define the symbol but did not match the declaration (declared void foo( int, double );, but defined void foo( double, int ). As with all other cases, the compiler will tell you the exact signature that it is looking for, make sure that you have defined that symbol, and not something close or similar, a particular corner case can be if you are using different calling conventions in the declaration and the definition, as they will look very similar in code.
In the case of libraries external code the complexity is in identifying what library needs to be linked for that symbol to be added, and that comes from the documentation of the lib. Beware that with static libraries the order of the libs in the linker command line affects the result.
To help you in finding what symbols are actually defined you can use nm (gcc, which is common among unix systems). So basically you can run nm against the object files/libs that you are linking and search for the symbol that the linker is complaining about. This will help in cases where the order is what makes the difference (i.e. the symbol is there, but the linker skipped it).
At runtime (thanks to Matthieu M. for pointing it out) you might have similar issues with dynamic libraries, if the wrong version of a library is found in the LD_LIBRARY_PATH you might end up with a library that does not have a required symbol.
Although they can be platform dependent, I have some "more complex" instances of some of the points from Andreas and David:
When dealing with shared libraries (.so or.dll) and linking against symbols which are not exported (dllimport/dllexport on Windows and visibility("default") with GCC on *nix)
Or similar: Linking against the static lib, while expecting a shared lib or vice versa. This one is bit similar to Mathieu's comment about linking against another, unexpected version of the library.
Creating a pure virtual classs and not providing an implementation for at least one method (causing no vtable to be available).
Actually a more complex case of declaring but not defining: The linking errors you can get when dealing with large, nested templates. Finding out what was not defined can be difficult with large error messages.
For most cases when you get a symbol not found/undefined symbol or sometimes even a "duplicate symbol" error, they usually stem from the fact that the linker is unable to find the symbol in the project that you are trying to build.
The best way to go about it is to look at the map file generated or a symbol table that is the output of the compiler. It may look something like this:
This will allow you to see if the symbol is present or not. Also, there might be other esoteric problems such as compiler optimizations that might cause a symbol duplication especially with inline assembly. These are about the hardest to detect.
As for good resources and materials, I don't have many good references. When I did ask around back then, most of the senior engineers have actually learned from their own experiences.
But I'm sure that's where forums such as these are present to help us expedite such knowledge acquisition.
Hope it helped :)
Cheers!
I assume you're referring to the linker error. Here's a list from the top of my head in what I think most-to-least common:
You forgot to tell the linker about a dependency (e.g. a LIB-file).
You have a class with a static data member and forgot to initialize it (only C++).
You declared a function not purely virtual and forgot to implement it.
You forgot to implement a function that you called from another function (only C, C++ will give a compiler error which is much easier to find).
You declared an external variable and forgot to initialize it.
The declaration of the function doesn't match the implementation (only C++, C will accept it and might die horribly).
You forgot to implement a function that you declared and called from another function.
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.
I'm using boost::function to enable the passing of a function to a Button constructor so it holds that function. Calling it whenever it is activated.
typedef boost::function< void() > Action;
In my TitleState I've constructed a Button like this.
m_play(
ButtonAction, // This is where I pass a function to Button's Action argument
sf::Vector2f( 500, 400 ),
sf::IntRect( 500, 400, 700, 500 )
)
where ButtonAction is a static void function privately held in TitleState's header, defined in the implementation file as simply outputting to the console via std::cout (just as a test for whether it is working).
In my code, if the mouse clicks a button in TitleState's HandleEvents function, the program calls that button's Activate function which looks like this.
void Button::Activate() const {
m_action(); // m_action is the Action member that holds the ButtonAction I passed earlier
}
The problem is that, when the program tries to link I get this error....
unresolved external symbol "public: void __thiscall Button::Activate(void)" (?Activate#Button##QAEXXZ) referenced in function "public: virtual void __thiscall TitleState::HandleEvents(void)" (?HandleEvents#TitleState##UAEXXZ)
I'm not sure what the problem is besides that the linker can't find the definition of the function. Everything is #included or declared properly. Any assistance is appreciated. Thanks.
P.S. When I used the BoostPro installer, I only installed the single-threaded stuff and none of the multi-threaded stuff. Could this be a reason why it isn't working? I read that linker problems can occur when libraries are linking in different ways. If this could be an issue, I'll add that I'm also using the SFML library.
Add the library option when you are linking your program:
g++:
g++ -L/your/library/path -lyour_library_name
vc++:
using boost with vc++
I'm not sure what the problem is. Everything is #included or declared properly. Any assistance is appreciated. Thanks.
That just means the compiler finds the declaration. But the linker has to find the definitions of the symbols. (See this SO question for what's the difference between a declaration and a definition.) You need to provide it with the library. If you're using GCC, follow Phong's advice.
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.