views:

417

answers:

2

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.

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

5>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!

A: 

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.

JaredPar
Vector::Vector( void ){// Do NOTHING!}class Vector{ friend class Matrix;public: Vector( void ) {} Vector( UNDEFINED ); Vector( ZERO ); Vector( int x, int y, int z = 0, int w = 0 ); Vector( float x, float y, float z = 0.f, float w = 0.f ); ~Vector( void ) { }.. more stuff ..}
+1  A: 

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() {
   // ...
}
dirkgently
All of my definitions are defined in the header outside the class definition.
Aha! That is the problem. I have given you the possible solution(s). See my examples above.
dirkgently
Make all definitions inline, follow the last example for the longer functions, and for the shorter ones, the second one. Cheers!
dirkgently
Additionally, you could take out all definitions and put them in an implementation file (which is what most people do for complex classes) as JaredPar mentioned.
dirkgently