Custom class generates error LNK2019. VC++ 2005 Express.

Started by
1 comment, last by rewt 18 years, 4 months ago
Happy Holidays. I am trying to venture into the world of game programming. I've managed to get simple mouse control, sprite rendering and text rendering via DX9. However, I want to start structuring my code a little more before it becomes unmanagable. So I am trying to pull together a simple 2D engine of sorts. However, my Vector2D template class seems to be generating LNK2019 errors in my Mouse class. Specifically when I try to access the Vector2D::getX() or Vector2D::getY() methods in my Mouse::setPosition(const Vector2D<int> &pos) method. I have been trying to locate the source of the issue but I cannot seem to find it. I am hoping that someone might know what might be wrong. The source is shown below. The specific error is:

error LNK2019: unresolved external symbol "public: int __thiscall Daedelus::Vector2D<int>::getY(void)const " (?getY@?$Vector2D@H@Daedelus@@QBEHXZ) referenced in function "public: virtual void __thiscall Daedelus::Mouse::setPosition(class Daedelus::Vector2D<int> const &)" (?setPosition@Mouse@Daedelus@@UAEXABV?$Vector2D@H@2@@Z) Mouse.obj

anderror LNK2019: unresolved external symbol "public: int __thiscall Daedelus::Vector2D<int>::getX(void)const " (?getX@?$Vector2D@H@Daedelus@@QBEHXZ) referenced in function "public: virtual void __thiscall Daedelus::Mouse::setPosition(class Daedelus::Vector2D<int> const &)" (?setPosition@Mouse@Daedelus@@UAEXABV?$Vector2D@H@2@@Z) Mouse.obj

// Vector2D.h
#pragma once

namespace Daedelus
{
	template<class T>
	class Vector2D
	{
		private:
			T m_x;
			T m_y;
		public:
			Vector2D(void);
			Vector2D(T x, T y);
			~Vector2D(void);

			T getX() const;
			T getY() const;
	};
}



// Vector2D.cpp
#include "Vector2D.h"

namespace Daedelus
{
	template<class T>
	Vector2D<T>::Vector2D(void)
	{
		m_x = 0;
		m_y = 0;
	}

	template<class T>
	Vector2D<T>::Vector2D(T x, T y)
	{
		m_x = x;
		m_y = y;
	}

	template<class T>
	Vector2D<T>::~Vector2D(void)
	{
	}

	template<class T>
	T Vector2D<T>::getX() const
	{
		return m_x;
	}

	template<class T>
	T Vector2D<T>::getY() const
	{
		return m_y;
	}
}



// IMouse.h
#pragma once
#include "Vector2D.h"

namespace Daedelus
{
	/// Button mappings for the mouse.
	enum E_MOUSE_BUTTON
	{
		EMB_LEFT = 0,
		EMB_RIGHT = 1,
		EMB_WHEEL = 2
	};

	/// Interface for querying the mouse.
	class IMouse
	{
		public:
			virtual ~IMouse(void) {};
			virtual void setPosition(const Vector2D<int> &pos) = 0;
	};
}



// Mouse.h
#pragma once

#include <dinput.h>
#include "Vector2D.h"
#include "IMouse.h"

namespace Daedelus
{
	/// Implements IMouse
	/// This implementation utilizes DirectInput
	class Mouse : public IMouse
	{
		private:
			// private variables omitted for clarity
		public:
			Mouse(IDirectInput8* pDirectInput, HWND hWnd);
			~Mouse(void);

			void setPosition(const Vector2D<int> &pos);
	};
}



// Mouse.cpp
#include "Mouse.h"

namespace Daedelus
{
	Mouse::Mouse(IDirectInput8* pDirectInput, HWND hWnd)
	{
		// Mouse initialization omitted for clarity
	}

	/// Destructor.
	Mouse::~Mouse(void)
	{
		// Mouse cleanup omitted for clarity
	}

	/// Sets the position of the mouse cursor.
	void Mouse::setPosition(const Vector2D<int> &pos)
	{
		int x = pos.getX();  // LNK2019 Error
		int y = pos.getY();  // LNK2019 Error
		SetCursorPos(x, y);
	}
}


Advertisement
Unless your compiler supports the export keyword, and MSVC 2005 doesn't, then you can't put the definition of a template in a separate source file without explicit instantiation for specific types. Without explicit instantiation, the complete definition of the template needs to be available at point of instantiation, which means, in effect, that the definition needs to go into the header. (Or an inline file of some sort, etc.)

For more details see these articles: "Export" Restrictions, Part 1 and "Export" Restrictions, Part 2.
Thank you very much for your quick response. This solved my problem and those pages are excellent explanations for what was going wrong in my code. Not only is it nice to get something to work, but it is nice to know why it does. Kudos.

-Ryan

This topic is closed to new replies.

Advertisement