So I'm trying to build a small 3D engine as an exercise on VC++ 8.0. I have a MathLib static lib and a Render static lib that is being linked by my TestBed exe. Right now Render has two classes: Color and DXManager3D. Color includes my Vector.h from MathLib just fine, no problems.
The second I try to include Vector.h in DXManager3D it blows up on me, saying the symbol is defined twice, and the second definition is ignored (warning from lib). I thought maybe including it twice was causing this so as a test I removed Vector.h from Color.h and left it in DXManager3D.h - same problem. I have triple checked to make sure I have everything wrapped in ifndef to protect from this, so I am left scratching my head.
DXManager3D.obj : warning LNK4006: "public: __thiscall Math::Vector::Vector(void)" (??0Vector#Math##QAE#XZ) already defined in Render.obj; second definition ignored
What really confuses me is that when I build the Render.lib separate from TestBed, which should not be linking anything as it is a static lib, right? I still get the multiple symbol definition warnings. If I instantiate a DXManager3D in main my warnings become errors.
Render.lib(DXManager3D.obj) : error LNK2005: "public: __thiscall Math::Vector::Vector(void)" (??0Vector#Math##QAE#XZ) already defined in WinMain.obj
Yes, I have F1'd LNK4006 and LNK2005 and the solutions in the MSDN aren't working for me.
Sorry if this question has been asked before, I couldn't find anything solid to help me out using the search feature.
Thanks!
Is your Vector ctor defined in the header outside the class definition? Make it inline then i.e. change
class Vector {
public:
Vector();
// ...
};
Vector::Vector() {
// ...
}
to
class Vector {
public:
Vector() {}
// ...
};
or use an explicit inline qualification:
class Vector {
public:
Vector();
// ...
};
inline Vector::Vector() {
// ...
}
It looks like you have a linkage issue with your vector class. Based on your information it appears that the class is being linked into any lib which includes the header file. This is internal linkage, and you really want external linkage.
Can you post the contents of Vector.h, or at least the Vector() constructor? That should give us a clue to what is actually going on.
Linkage: http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/cplr020.htm
EDIT
Based on your comment, it appears that you have declared all of the functions in the header file outside the class library. You should put them into a non-header file (Vector.cpp file for instance).
This will give your program the appropriate linkage and you will be able to include Vector.h in both programs.
Related
So I was writing, as a small project, a stress test. Initially, to save time, I just plopped code in a header file. I decided to organise it a bit, and moved everything to a .cpp file and then wrote the header file, but VS2010 presented me with an LNK2019 that I can't seem to fix.
FSTRESS.cpp (Didn't include code, because I doubt it is relevant; ask if you need it)
FSTRESS.h
Main.cpp
The error:
error LNK2019: unresolved external symbol "public: static void __cdecl FSTRESS::Start(unsigned int,unsigned int,unsigned int)" (?Start#FSTRESS##SAXIII#Z) referenced in function _main C:\Programming\C++\FLOPS_Test\FSTRESS\FSTRESS\main.obj FSTRESS_Mk.II
Any ideas on why this is happening? I'm a bit of a C++ noob.
Thanks for any help :)
Your .cpp file is not defining the same classes as the ones you've declared in the .h, but creating different classes with the same name as those declared in the header. The correct way to do this is:
Header file:
class Foo
{
void Bar();
};
Implementation file:
void Foo::Bar()
{
// Do something
}
Alternately, you can declare the functions inline in the header file itself
class Foo
{
void Bar()
{
// Do something
}
};
In the latter case there's no need to create a separate implementation file. In fact, this is exactly what you're doing in fstress.cpp, but then you provide a duplicate declaration in fstress.h without actually defining that class anywhere.
So, you've actually got two separate definitions of the x86 and FSTRESS classes, one in the header file and one in the .cpp file. You're allowed to do that provided that the definitions are identical, but they aren't -- the one in the .cpp file has a bunch of inline code, which isn't there in the one in the header file. (Look up "one definition rule" for more information about this.)
What you actually want to do is this. Your header file is fine (or, at least, I don't see anything conspicuously wrong with it). The .cpp file should (1) #include the header file, and then (2) provide definitions for the member functions, looking like this:
static void FSTRESS::Start(unsigned aMode, unsigned aTest, unsigned aThreads) {
// code goes here
}
(When you have a source file and a corresponding header file, the source file should always #include the header file. This helps to make sure that if there's an inconsistency it gets caught tidily at compile time. I can't tell whether you were already doing that because the top of FSTRESS.cpp is invisible in your screen captures. It might have been better to post the code as text :-).)
As an aside, don't use names that begin with an underscore. A large portion of the space of such names is "reserved", meaning that the C++ implementation can use them internally and Bad Things can happen if your use clashes with its use. It's best just to avoid them all, because that way you don't have to remember what the exact rule is and neither does anyone else reading your code.
You can't just paste the contents of the class declaration with inlined code from the header file into the .cpp file and expect it to work. The implementation of FSTRESS::Start() needs to look morel like the following when you separate it from the class declaration:
void FSTRESS::Start(unsigned _aMode, unsigned _aTest, unsigned _aThreads)
{
//...
}
Also, you should #include "FSTRESS.h" in the FSTRESS.cpp file so there's exactly on declaration of the class that everyone uses (include the implementation bits in FSTRESS.cpp).
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?
When I try to build my application the linker gives loads of errors like this one:
modlauch.obj : error LNK2005: "public:
virtual __thiscall
lolbutton::~lolbutton(void)"
(??1lolbutton##UAE#XZ) already defined
in lolbutton.obj
I suspect it has something to do with misconfigured compiler but I don't know how to fix it. My class is only included once so I don't think it has anything to do with the code. I have tried rebuilding and cleaning the project but it didn't help.
Can someone suggest a solution to this problem? My platform is Win32(C++) and I'm using MFC.
You'll get the linker error when you wrote the class like this:
lolbutton.h:
class lolbutton {
public:
virtual ~lolbutton();
};
lolbutton::~lolbutton() {
// something...
}
You won't get it when you write it like this:
class lolbutton {
public:
virtual ~lolbutton()
{
// inlined something...
}
};
Fix the linker error by moving the destructor definition from the .h file to a .cpp file. This ensures there is only one definition of the destructor.
do you by any chance include your lolbutton.h file more than once? like so:
//file: something.h
#include <lolbutton.h>
//... do code
//file: something_other.h
#include <lolbutton.h>
//file: main.cpp
#include <something.h>
#include <something_other.h>
At a guess - without seeing the code - did you by any chance put the destructor for lolbutton in the header without declaring it inline? From your description this is the likely culprit if you end up with instances of the destructor in multiple translation units.
I would go with either multiple includes of lolbutton.h, hence my comment about wrapping the contents in an "if !defined someUUID" block or perhaps it could be to do with the use of precompiled headers.
I currently have a program where my main code is in a file main.cpp.
Main.cpp includes a header file "class.h" that declares a class that is used within main.cpp.
Also in main.cpp I have function declarations that declare the functions I use within main.cpp.
The code for these functions is in a separate .cpp file fucntions.cpp.
Like main.cpp, functions.cpp also includes class.h as the class type is used within the functions.
class.h contains the class declaration only.
The implementation code for class.h is in a separate .cpp file classimplementation.cpp.
It all works fine until I try to make the class in class.h a template class.
Then I get linking problems. Research and testing has shown me that this is because the definition of the template class functions needs to reside in class.h with the declaration.
I therefore took the required code out of classimplementations.cpp and put it into class.h.
This did solve my original linking issues but instead I get more linking errors that seem to be telling me I am trying to redefine the functions that I moved to into class.h.
This I think is because class.h is being called by main.cpp and again by functions.cpp.
Therefore the functions in class.h are being defined twice:
Error 41 error LNK2005: "public: __thiscall RecordPocket::RecordPocket(int)" (??0?$RecordPocket#VT####QAE#H#Z) already defined in classimplementation.obj functions.obj
I know that class implementation code should really be kept out of include files but due to the template class limitation of having to keep the class functions local I appear (in my novice mind) to have no choice.
Has anyone been in this scenario and can offer any advice.
I have tried surrounding the functions I moved from classimplementation.cpp to class.h with the standard ifndef CLASSIMP, #define CLASSIMP code and PRAGMA ONCE but neither make any difference.
If all else fails I will move the functions from functions.cpp into main.cpp so that class.h gets called just the once but I’d rather find out what I’m doing wrong as I’m sure it will happen again.
You could keep the template functions inside the template<> class what{/HERE/};
template<typename T>
class MyTempClass{
void myFunctions{
// code here
}
}
EDITED: I removed the code corrected by Glen
I think your problem is revolves around these issues. As you have implied any template function definition (i.e. template function of member function of a template class) needs to be fully expressed in the .h file because when the compiler finds a specific instance of the template it needs to build the function.
You figured this out and moved some implementation into your class.h file. Now if the linker find a MyFunction() in more than one module then is just discards one of them a no linker error is reported.
However you can't define the same non-template function in two different modules as this generates the error you are getting above. So I suspect you also moved some non-template functionality into the .h file; thus including it in two separate obj files and generating the linker error. This theory is support by your quoted error message as I note __thiscall RecordPocket::RecordPocket(int) does not appear to be template.
Background
I have a project named PersonLibrary which has two files.
Person.h
Person.cpp
This library produces a static library file. Another project is TestProject which uses the PersonLibrary (Added though project dependencies in VS008). Everything worked fine until I added a non-member function to Person.h. Person.h looks like
class Person
{
public:
void SetName(const std::string name);
private:
std::string personName_;
};
void SetPersonName(Person& person,const std::string name)
{
person.SetName(name);
}
Person.cpp defines SetName function. When I try to use SetPersonName from TestProject, I get error LNK2005: already defined. Here is how I used it
#include "../PersonLibrary/Person.h"
int main(int argc, char* argv[])
{
Person person;
SetPersonName(person, "Bill");
return 0;
}
Workarounds tried
1 - I have removed the Person.cpp and defined the whole class in Person.h. Error gone and everything worked.
2 - Changed the SetPersonName modifier to static. Like the below
static void SetPersonName(Person& person,const std::string name)
{
person.SetName(name);
}
Questions
Why the code shown first is not working as I expected?
What difference static made here?
What is the approapriate solution for this problem?
Thanks
You either have to
move SetPersonName's definition to a .cpp file, compile and link to the resulting target
make SetPersonName inline
This is a well known case of One Definition Rule violation.
The static keyword makes the function's linkage internal i.e. only available to the translation unit it is included in. This however is hiding the real problem. I'd suggest move the definition of the function to its own implementation file but keep the declaration in the header.
When you compile you're library, its lib file contains a definition for SetPersonName. When you compile your program that uses the library, since it includes the header, and you've written the code inline in the header it also compiles in a definition for SetPersonName. Two definitions for the same function aren't (generally) allowed. The static keyword tells the compiler that the function shouldn't be exposed outside of the current translation unit (discrete piece of code you are compiling), so the definition in the library isn't visible to the linker.
The appropriate solution to this problem depends on your goals. Header files with static function declarations is almost never what you want. From a design standpoint I would recommend getting rid of SetPersonName altogether, and just use Person::SetName.
However, failing that, I would implement it much like you've done for the rest of your functionality, declarations in the header, and implementation in the .cpp. Inline functions associated with a library will tend to diminish many of the advantages of using a library in the first place.
By declaring the function static you are scoping it to the current translation unit, so in effect you have added a new SetPersonName function in your main file, and would be calling that not the one defined in the library.
The correct solution is to declare SetPersonName as extern in person.h and implement it in person.cpp
Person.h
extern void SetPersonName(Person& person,const std::string name);
Person.cpp
void SetPersonName(Person& person,const std::string name)
{
person.SetName(name);
}
The function SetPersonName will be compiled into each objectfile that includes the Person.h file, thus making the linker seeing several functions and giving the error.
By writing static you state that the function will only be visible within a single objectfile. You will still get several functions in you binary but now you will not get the errors.
Try to write inline before the function like
inline void SetPersonName(Person& person,const std::string name)
{
person.SetName(name);
}
...because the function is pretty simple it is OK I think to have it as an inline. An inline will place the necessary code where the function is used, without actually creating a function to be called.
A solution would be to make that function a static method. That will stop the "already defined" errors.
I had a similar situation as described clearly by #logan-capaldo above.
A CPP source file (myfile.cpp) contained a function MyFunction. When building, this got compiled into myfile.obj. But the main CPP file (main.cpp) also included myfile.cpp, so the function MyFunction was being included/compiled/linked twice, leading to the "LNK2005 already defined" error.
This is messy but I didn't have time to fix it properly. The quickest fix (in VS Express 2012) was to right-click myfile.cpp in Solution Explorer, go to Properties and change Excluded From Build to Yes. I guess this prevents one of the OBJ files from being created and/or linked and so removes the error.
For anyone landing here dealing with this error in a Qt project, make sure you don't have any non-signal functions defined under signals: in your header files.
Incorrect, throws LNK2005 on Foo::promiseData():
class Foo : public QObject {
Q_OBJECT
public:
explicit Foo(QObject* parent = nullptr);
signals:
void dataReady(QList<QObject*> data) const;
void promiseData() const; // <-- This function is not supposed to be a signal.
Correct:
class Foo : public QObject {
Q_OBJECT
public:
explicit Foo(QObject* parent = nullptr);
void promiseData() const;
signals:
void dataReady(QList<QObject*> data) const;