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.
Related
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.
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 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.