Jump to content
  • Advertisement
Sign in to follow this  
MrLloyd1981

Quite literally the most annoying LNK2019 in the world

This topic is 2749 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Ok I've been tearing my hair out over this most tedious of link errors. Using a process of elimination it seems that for some reason when I'm passing a Vector3 class of my own making into a function it is causing a


1>sphereRender.obj : error LNK2019: unresolved external symbol "public: static class Vector3 __cdecl Matrix4::Multiply(class Vector3 const &)" (?Multiply@Matrix4@@SA?AVVector3@@ABV2@@Z) referenced in function "void __cdecl drawSphere(void)" (?drawSphere@@YAXXZ)

Error and not completely linking, but i fail to understand why at all, my Vector3 class has NO static members/methods, and this function being called is a non static member func of a custom matrix class. I've looked at my constructor code and tried a few things to no avail...PLEASE give me a hint or some advice

Here's my Vector3 header:

#ifndef _VECTOR3_H
#define _VECTOR3_H

class Vector3
{
public:
Vector3(float xVal,float yVal,float zVal){ x = xVal; y = yVal; z = zVal;}
~Vector3() {};

//setters
void Set(float xVal,float yVal, float zVal) {x = xVal;y = yVal; z = zVal;}
void SetX(float xVal) {x = xVal;}
void SetY(float yVal) {y = yVal;}
void SetZ(float zVal) {z = zVal;}


//getters
float GetX()const {return x;}
float GetY()const {return y;}
float GetZ()const {return z;}

//operations
Vector3 Addition(const Vector3& rhs);
Vector3 Subtraction(const Vector3& rhs);
Vector3 operator+(const Vector3& rhs);
Vector3 operator-(const Vector3& rhs);
Vector3 operator*(float scalar);
const float& operator[](int index) const;
float& operator[](int index);

//other operations, dot product etx
float DotProduct(const Vector3& otherVec);
Vector3 CrossProduct(const Vector3& otherVec);

float Length()const;
Vector3 Normalize()const;

private:
float x,y,z;
};

#endif



here's my matrix header/implementation
//Matrix4.h interface for the matrix class, row major format
#ifndef _MATRIX4_H
#define _MATRIX4_H
#include "Vector3.h"
#include "Vector4.h"

class Matrix4
{
public:
//default constructor - creates identity matrix
Matrix4();
~Matrix4() {};

//setter
void Set(int i, int j,float val);
float Get(int i, int j)const;

//operations
Matrix4 Multiply(const Matrix4& rhs);
Vector3 Multiply(const Vector3& rhs);
Vector4 Multiply(const Vector4& rhs);
static Matrix4 MakeXRotationMatrix(float angle);
static Matrix4 MakeYRotationMatrix(float angle);
static Matrix4 MakeZRotationMatrix(float angle);
static Matrix4 MakeArbitraryRotationMatrix(float angle,Vector3 axis);
static Matrix4 MakeNonUniformScalingMatrix(float xFactor,float yFactor, float zFactor);
static Matrix4 MakeTranslationMatrix(float tX,float tY, float tZ);
private:
float elems[4][4];

};

#endif


//Matrix4.cpp - implementation for all the methods of the matrix4 class
#include "Matrix4.h"
#include <math.h>

Matrix4::Matrix4()
{
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 4; j++)
{
elems[j] = 0.0f;
}
}

elems[0][0] = elems[1][1] = elems[2][2] = elems[3][3] = 1;
}

void Matrix4::Set(int i, int j,float val)
{
elems[j] = val;
}

float Matrix4::Get(int i,int j)const
{
return elems[j];
}

Matrix4 Matrix4::Multiply(const Matrix4& rhs)
{
Matrix4 newMatrix;

for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 4; j++)
{
float total = 0.0f;

for(int k = 0; k < 4; k++)
{
total += elems[k] * rhs.Get(k,j);
}

newMatrix.Set(i,j,total);
}
}

return newMatrix;
}


Vector4 Matrix4::Multiply(const Vector4& rhs)
{
Vector4 newVector(0.0f,0.0f,0.0f);

for(int i = 0; i < 4; i++)
{
newVector = 0.0f;
for(int j =0; j < 4; j++)
{
newVector += elems[j] *rhs[j];
}
}

return newVector.DeHomogenize();
}

Vector3 Matrix4::Multiply(const Vector3& rhs)
{
Vector4 newVector(rhs.GetX(),rhs.GetY(),rhs.GetZ());
newVector = Multiply(newVector);
Vector3 newVector2(newVector.GetX(),newVector.GetY(),newVector.GetZ());
return newVector2;
}


Matrix4 Matrix4::MakeXRotationMatrix(float angle)
{
Matrix4 Xmatrix;
Xmatrix.Set(1,1,cos(angle));
Xmatrix.Set(1,2,-sin(angle));
Xmatrix.Set(2,1,sin(angle));
Xmatrix.Set(2,2,cos(angle));

return Xmatrix;
}

Matrix4 Matrix4::MakeYRotationMatrix(float angle)
{
Matrix4 Ymatrix;
Ymatrix.Set(0,0,cos(angle));
Ymatrix.Set(0,2,sin(angle));
Ymatrix.Set(2,0,-sin(angle));
Ymatrix.Set(2,2,cos(angle));

return Ymatrix;
}

Matrix4 Matrix4::MakeZRotationMatrix(float angle)
{
Matrix4 Zmatrix;
Zmatrix.Set(0,0,cos(angle));
Zmatrix.Set(0,1,-sin(angle));
Zmatrix.Set(1,0,sin(angle));
Zmatrix.Set(1,1,cos(angle));

return Zmatrix;
}

Matrix4 Matrix4::MakeArbitraryRotationMatrix(float angle,Vector3 axis)
{
axis = axis.Normalize();

Matrix4 rotMatrix;
rotMatrix.Set(0,0,1.0f + ((1.0f-cos(angle)*(pow(axis.GetX(),2)-1.0f))));
rotMatrix.Set(0,1,(-axis.GetZ()*sin(angle))+ (1.0f-cos(angle)*axis.GetX()*axis.GetY()));
rotMatrix.Set(0,2,axis.GetY() * sin(angle)+(1.0f-cos(angle))*axis.GetX()*axis.GetZ());
rotMatrix.Set(1,0,axis.GetZ()*sin(angle)+(1.0f-cos(angle))*axis.GetY()*axis.GetX());
rotMatrix.Set(1,1,1.0f +(1.0f- cos(angle))*(pow(axis.GetY(),2)-1.0f) );
rotMatrix.Set(1,2,-axis.GetX()*sin(angle)+(1.0f-cos(angle))*axis.GetY()*axis.GetZ());
rotMatrix.Set(2,0,-axis.GetY()*sin(angle)+(1.0f-cos(angle))*axis.GetZ()*axis.GetX());
rotMatrix.Set(2,1,axis.GetX()*sin(angle)+(1.0f-cos(angle))*axis.GetZ()*axis.GetY());
rotMatrix.Set(2,2,1.0f+(1.0f-cos(angle))*(pow(axis.GetZ(),2)-1.0f));

return rotMatrix;
}

Matrix4 Matrix4::MakeNonUniformScalingMatrix(float xFactor,float yFactor,float zFactor)
{
Matrix4 scaleMatrix;
scaleMatrix.Set(0,0,xFactor);
scaleMatrix.Set(1,1,yFactor);
scaleMatrix.Set(2,2,zFactor);
return scaleMatrix;
}

Matrix4 Matrix4::MakeTranslationMatrix(float tX,float tY, float tZ)
{
Matrix4 translationMatrix;

translationMatrix.Set(0,3,tX);
translationMatrix.Set(1,3,tY);
translationMatrix.Set(2,3,tZ);
return translationMatrix;
}



and here's the piece of offending code in another file:

void drawSphere()
{
glColor3f(0.0f,0.0f,0.0f);
float interval = (2 * PI)/10;

Matrix4 tempMatrix;
Vector3 startVector(5.0,0,0);
Vector3 tempVector;

for(float f = 0; f < 2* PI; f+=interval)
{
tempMatrix = Matrix4::MakeZRotationMatrix(f);
tempVector = tempMatrix.Multiply(startVector);

glVertex3f(startVector.GetX(),startVector.GetY(),startVector.GetZ());

}

}

Share this post


Link to post
Share on other sites
Advertisement
When you declare some of the Matrix4:: member functions you make them static. But when you *define* them you don't make them static. Make the definitions like this:

static Matrix4 Matrix4::MakeZRotationMatrix(float angle)
{
Matrix4 Zmatrix;
Zmatrix.Set(0,0,cos(angle));
Zmatrix.Set(0,1,-sin(angle));
Zmatrix.Set(1,0,sin(angle));
Zmatrix.Set(1,1,cos(angle));

return Zmatrix;
}

The fact that you aren't matching them up correctly could be confusing the compiler.

Share this post


Link to post
Share on other sites
As with "virtual", the function definition doesn't need the "static" on it. (In fact, some compilers will complain at you if you try.)

Things to check:
Have you added Matrix4.cpp to your project?
If your math classes are in a static library, have you added it as a dependency to the main project?

Share this post


Link to post
Share on other sites

As with "virtual", the function definition doesn't need the "static" on it. (In fact, some compilers will complain at you if you try.)

Things to check:
Have you added Matrix4.cpp to your project?
If your math classes are in a static library, have you added it as a dependency to the main project?


Hi guys, thanks for both your replies.

Yes, Matrix4.cpp is part of my project, however how do I add the static library as a dependency? I'm totally ignorant regarding the method to do that! My compiler/IDE is visual studio express 2010.

Share this post


Link to post
Share on other sites

As with "virtual", the function definition doesn't need the "static" on it. (In fact, some compilers will complain at you if you try.)

Things to check:
Have you added Matrix4.cpp to your project?
If your math classes are in a static library, have you added it as a dependency to the main project?


he is using std::math. He shouldn't need the .h though. just <math>.

edit: might be a namespace thing?

edit2:
can you post your Vector4.h?

edit3: just so you are aware your drawSphere() does nothing right now. Pretty sure you want:
glVertex3f(tempVector.GetX(),tempVector.GetY(),tempVector.GetZ());

Share this post


Link to post
Share on other sites
I threw your code into my VS2010, I had to comment out everything using vector4 because you didn't post that file.

Mine comes up with on this line:
Vector3 tempVector;

'Vector3' : no appropriate default constructor available

I changed it to Vector3 tempVector(0,0,0);
and it compiled fine for me (without all of the vector 4 references though)

Share this post


Link to post
Share on other sites
Sometimes a clean build can sort out strange or "impossible" errors. Another thing I try is to add a #error directive to the source file that I think contains the correct definition, this should trigger it to be rebuilt and the compiler should spit out an error message.

Share this post


Link to post
Share on other sites
If Matrix4.cpp is part of your main project (not a separate static library project) and not marked as "Exclude from Build" under Properties, it should be compiling and linking properly. Doing a clean build ("Rebuild Solution") might help...

Share this post


Link to post
Share on other sites
Sorry to be nitpicky while not being able to help you with your issue, but you shouldn't use _VECTOR3_H in the include guard: Things that start with "_" are reserved to the implementation.

Share this post


Link to post
Share on other sites
//vector4.h - interface for vector4 class
#ifndef _VECTOR_4
#define _VECTOR_4

class Vector4
{
public:
Vector4(float xVal, float yVal, float zVal):x(xVal),y(yVal),z(zVal),w(1.0){};
~Vector4(){};

//setters
void Set(float xVal,float yVal, float zVal) {x = xVal;y = yVal; z = zVal;}
void SetX(float xVal) {x = xVal;}
void SetY(float yVal) {y = yVal;}
void SetZ(float zVal) {z = zVal;}


//getters
float GetX()const {return x;}
float GetY()const {return y;}
float GetZ()const {return z;}

//operations
Vector4 Addition(const Vector4& rhs);
Vector4 Subtraction(const Vector4& rhs);
Vector4 operator+(const Vector4& rhs);
Vector4 operator-(const Vector4& rhs);
const float& operator[](int index) const;
float& operator[](int index);

Vector4 DeHomogenize()const;

private:
float x,y,z,w;
};
#endif


//vector4.cpp - implementation of vector class
#include "Vector4.h"


Vector4 Vector4::Addition(const Vector4& rhs)
{
Vector4 newVector(x+rhs[0],y+rhs[1],z+rhs[2]);
return newVector;
}

Vector4 Vector4::Subtraction(const Vector4& rhs)
{
Vector4 newVector(x-rhs[0],y-rhs[1],z-rhs[2]);
return newVector;
}

Vector4 Vector4::operator+(const Vector4& rhs)
{
Vector4 newVector(x+rhs[0],y+rhs[1],z+rhs[2]);
return newVector;
}

Vector4 Vector4::operator-(const Vector4& rhs)
{
Vector4 newVector(x-rhs[0],y-rhs[1],z-rhs[2]);
return newVector;
}

const float& Vector4::operator[](int index)const
{
switch(index)
{
case 0:
return x;
break;
case 1:
return y;
break;
case 2:
return z;
break;
case 3:
return w;
}
}

float& Vector4::operator[](int index)
{
switch(index)
{
case 0:
return x;
break;
case 1:
return y;
break;
case 2:
return z;
break;
case 3:
return w;
}
}

Vector4 Vector4::DeHomogenize()const
{
Vector4 newVector(x,y,z);
newVector[3] = 0.0f;
return newVector;
}



The above is the code for Vector4. However I have now completely changed the Matrix4 class to no longer use static methods as I felt I was forcing a square peg into a round hole, and now managed to get my sphere to draw. I'm getting strange colouring issues and problems with applying my matrix transformations to an STL vector of Vector3s, but as since this is unrelated to a LNK 2019 I'll be giving it its own thread. Thanks so much for all of your help and interest. Just in case you're interested I'm going to post my new Matrix4 code below:


//Matrix4.h interface for the matrix class, row major format
#ifndef _MATRIX4_H
#define _MATRIX4_H
#include "Vector3.h"
#include "Vector4.h"

class Matrix4
{
public:
//default constructor - creates identity matrix
Matrix4();
Matrix4(double,double,double,double,double,double,double,double,double,double,double,double,double,double,double,double);
~Matrix4() {};

//setter
void Set(int i, int j,double val);
double Get(int i, int j)const;
double* GetPointer();

//operations

Matrix4 Multiply(const Matrix4& rhs);
Matrix4 operator*(const Matrix4& rhs);
Vector3 Multiply(const Vector3& rhs);
Vector4 Multiply(const Vector4& rhs);

void identity();
void MakeXRotationMatrix(float angle);
void MakeYRotationMatrix(float angle);
void MakeZRotationMatrix(float angle);
void MakeArbitraryRotationMatrix(float angle,Vector3 axis);
void MakeNonUniformScalingMatrix(double xFactor,double yFactor,double zFactor);
void MakeTranslationMatrix(double tX,double tY,double tZ);
private:
double elems[4][4];

};

#endif



//Matrix4.cpp - implementation for all the methods of the matrix4 class
#include "Matrix4.h"
#include <math.h>

Matrix4::Matrix4()
{
identity();
}

Matrix4::Matrix4(double m00,double m01,double m02,double m03,
double m10,double m11,double m12,double m13,
double m20,double m21,double m22,double m23,
double m30,double m31,double m32,double m33)
{
elems[0][0] = m00;
elems[0][1] = m01;
elems[0][2] = m02;
elems[0][3] = m03;
elems[1][0] = m10;
elems[1][1] = m11;
elems[1][2] = m12;
elems[1][3] = m13;
elems[2][0] = m20;
elems[2][1] = m21;
elems[2][2] = m22;
elems[2][3] = m23;
elems[3][0] = m30;
elems[3][1] = m31;
elems[3][2] = m32;
elems[3][3] = m33;
}

void Matrix4::Set(int i, int j,double val)
{
elems[j] = val;
}

double Matrix4::Get(int i,int j)const
{
return elems[j];
}

double* Matrix4::GetPointer()
{
return &elems[0][0];
}

Matrix4 Matrix4::Multiply(const Matrix4& rhs)
{
Matrix4 newMatrix;

for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 4; j++)
{
float total = 0.0f;

for(int k = 0; k < 4; k++)
{
total += elems[k] * rhs.Get(k,j);
}

newMatrix.Set(i,j,total);
}
}

return newMatrix;
}

Matrix4 Matrix4::operator*(const Matrix4& rhs)
{
Matrix4 newMatrix;

for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 4; j++)
{
float total = 0.0f;

for(int k = 0; k < 4; k++)
{
total += elems[k] * rhs.Get(k,j);
}

newMatrix.Set(i,j,total);
}
}

return newMatrix;
}


Vector4 Matrix4::Multiply(const Vector4& rhs)
{
Vector4 newVector(0.0f,0.0f,0.0f);

for(int i = 0; i < 4; i++)
{
double newVal = 0.0f;
for(int j =0; j < 4; j++)
{
newVal += elems[j] * rhs[j];
}
newVector = newVal;
}

newVector = newVector.DeHomogenize();
return newVector;
}

Vector3 Matrix4::Multiply(const Vector3& rhs)
{
Vector4 newVector(rhs.GetX(),rhs.GetY(),rhs.GetZ());
newVector = Multiply(newVector);
Vector3 newVector2(newVector.GetX(),newVector.GetY(),newVector.GetZ());
return newVector2;
}

void Matrix4::identity()
{
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 4; j++)
{
elems[j] = 0.0f;
}
}

elems[0][0] = elems[1][1] = elems[2][2] = elems[3][3] = 1;
}

void Matrix4::MakeXRotationMatrix(float angle)
{
identity();
elems[1][1] = cos(angle);
elems[1][2] = -sin(angle);
elems[2][1] = sin(angle);
elems[2][2] = cos(angle);

}

void Matrix4::MakeYRotationMatrix(float angle)
{
identity();
elems[0][0] = cos(angle);
elems[0][2] = sin(angle);
elems[2][0] = -sin(angle);
elems[2][2] = cos(angle);

}

void Matrix4::MakeZRotationMatrix(float angle)
{
identity();
elems[0][0] = cos(angle);
elems[0][1] = -sin(angle);
elems[1][0] = sin(angle);
elems[1][1] = cos(angle);
}

void Matrix4::MakeArbitraryRotationMatrix(float angle,Vector3 axis)
{
axis = axis.Normalize();
identity();

elems[0][0] =(1.0f + ((1.0f-cos(angle)*(pow(axis.GetX(),2)-1.0f))));
elems[0][1] =((-axis.GetZ()*sin(angle))+ (1.0f-cos(angle)*axis.GetX()*axis.GetY()));
elems[0][2] =(axis.GetY() * sin(angle)+(1.0f-cos(angle))*axis.GetX()*axis.GetZ());
elems[1][0] =(axis.GetZ()*sin(angle)+(1.0f-cos(angle))*axis.GetY()*axis.GetX());
elems[1][1] =(1.0f +(1.0f- cos(angle))*(pow(axis.GetY(),2)-1.0f) );
elems[1][2] =(-axis.GetX()*sin(angle)+(1.0f-cos(angle))*axis.GetY()*axis.GetZ());
elems[2][0] =(-axis.GetY()*sin(angle)+(1.0f-cos(angle))*axis.GetZ()*axis.GetX());
elems[2][1] =(axis.GetX()*sin(angle)+(1.0f-cos(angle))*axis.GetZ()*axis.GetY());
elems[2][2] =(1.0f+(1.0f-cos(angle))*(pow(axis.GetZ(),2)-1.0f));
}

void Matrix4::MakeNonUniformScalingMatrix(double xFactor,double yFactor,double zFactor)
{
identity();
elems[0][0] = xFactor;
elems[1][1] = yFactor;
elems[2][2] = zFactor;

}

void Matrix4::MakeTranslationMatrix(double tX,double tY,double tZ)
{
identity();

elems[0][3] =tX;
elems[1][3] =tY;
elems[2][3] =tZ;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!