compile error due to virtual function in dynamic link library - c++

in a MSVC dll project, i tried to create a dll containing a base class
//header file
class MATHLIBRARY_API Shape {
protected:
int width, height;
public:
Shape(int, int);
int area(void) { return -1; };
};
it's compiled successfully, but when adding a virtual specifier to the function
class MATHLIBRARY_API Shape {
protected:
int width, height;
public:
Shape(int, int);
virtual int area(void) { return -1; };
};
the compiler showed error msg
Error LNK2019 unresolved external symbol `__declspec(dllimport) const Shape::`vftable'" (__imp_??_7Shape##6B#) referenced in function "public: __thiscall Shape::Shape(int,int)" (??0Shape##QAE#HH#Z) Dll3 c:\Users\langj\source\repos\Dll3\Dll3\Dll3.obj 1
where could be the problem?

Related

LNK2019 Error when calling methods of a static member in .cpp file

I am getting these errors in my code, they are all related to one static member in my Game class.
Game.obj : error LNK2019: unresolved external symbol "public: class std::shared_ptr<class MainMenuScene> __thiscall SceneManager::AddScene<class MainMenuScene>(void)" (??$AddScene#VMainMenuScene###SceneManager##QAE?AV?$shared_ptr#VMainMenuScene###std##XZ) referenced in function "public: void __thiscall Game::init(char const *,int,int,bool)" (?init#Game##QAEXPBDHH_N#Z)
Game.obj : error LNK2019: unresolved external symbol "public: class std::shared_ptr<class GameSelectScene> __thiscall SceneManager::AddScene<class GameSelectScene>(void)" (??$AddScene#VGameSelectScene###SceneManager##QAE?AV?$shared_ptr#VGameSelectScene###std##XZ) referenced in function "public: void __thiscall Game::init(char const *,int,int,bool)" (?init#Game##QAEXPBDHH_N#Z)
Game.obj : error LNK2019: unresolved external symbol "public: class std::shared_ptr<class MainMenuScene> __thiscall SceneManager::ChangeScene<class MainMenuScene>(void)" (??$ChangeScene#VMainMenuScene###SceneManager##QAE?AV?$shared_ptr#VMainMenuScene###std##XZ) referenced in function "public: void __thiscall Game::init(char const *,int,int,bool)" (?init#Game##QAEXPBDHH_N#Z)
In my game.h I have:
#pragma once
class SceneManager;
using namespace std;
class Game {
public:
Game();
~Game();
void init(const char* title, int width, int height, bool fullscreen);
void handleEvents();
void update();
void render();
void clean();
bool isRunning() { return running; }
static SDL_Renderer * renderer;
static SceneManager * sceneManager;
};
The errors are happening in my game.cpp file in the init() method and my game.cpp looks like:
#include "Game.h"
#include "SceneManager.h"
#include "GameSelectScene.h"
#include "MainMenuScene.h"
SceneManager * Game::sceneManager = new SceneManager();
Game::Game() {}
Game::~Game() {}
void Game::init(const char* title, int width, int height, bool fullscreen) {
// I do some stuff up here
// Here is where I think errors are happening.
sceneManager->AddScene<MainMenuScene>();
sceneManager->AddScene<GameSelectScene>();
sceneManager->ChangeScene<MainMenuScene>();
}
My GameSelectScene.h and MainMenuScene.h are both subclasses of my Scene.h
and my SceneManager is where the AddScene and ChangeScene methods are defined
My SceneManager.h:
#pragma once
#include "Game.h"
#include "Scene.h"
#include <map>
#include <string>
#include <typeindex>
using namespace std;
class SceneManager {
public:
SceneManager();
~SceneManager();
void init();
void update();
void render();
template <typename T> std::shared_ptr<T> ChangeScene();
template <typename T> std::shared_ptr<T> AddScene();
private:
std::map<type_index, std::shared_ptr<Scene>> scenes;
std::shared_ptr<Scene> currentScene;
};
SceneManager.cpp:
#include "SceneManager.h"
SceneManager::SceneManager() {}
SceneManager::~SceneManager() {}
// I define the init() update() and render()
template <typename T> std::shared_ptr<T> SceneManager::ChangeScene() {
type_index index(typeid(T));
currentScene = scenes[index];
return static_pointer_cast<T>(scenes[index]);
}
template <typename T> std::shared_ptr<T> SceneManager::AddScene() {
T scene = new T();
scenes[std::type_index(typeid(*scene))] = scene;
return scene;
}
If I remove my AddScene and ChangeScene method calls in the game.cpp file everything compiles correctly and the update, init and render methods defined in the SceneManager run perfectly. I have been researching this issue and walked through all the problems described in MSDN LNK2019 Error
Template functions must be defined in header files, not cpp.
Why can templates only be implemented in the header file?

vs c++ dll - scalar deleteing destructor

I'm programing in visual studio c++. I have Field, IField, Map and IMap in DLL. I create interfaces IField and IMap to have access to Field and Map in unit test. When i run this simple code in unit test:
IMap m;
IField f(3, 4);
m.shoot(f);
I have following error:
LNK2019 unresolved external symbol "public: virtual __thiscall
Field::~Field(void)" (??1Field##UAE#XZ) referenced in function
"public: virtual void * __thiscall Field::`scalar deleting
destructor'(unsigned int)" (??_GField##UAEPAXI#Z) TestShipGameDll
#pragma once
class Field
{
public:
Field(int x, int y) : x(x), y(y) {}
virtual ~Field() {}
protected:
int x;
int y;
};
.
#ifdef IFIELD_EXPORTS
#define IFIELD_API __declspec(dllexport)
#else
#define IFIELD_API __declspec(dllimport)
#endif
class IField :
public Field
{
public:
IFIELD_API IField(int x, int y) :Field(x, y)
IFIELD_API virtual ~IField() {}
};
.
class Map
{
public:
Map();
virtual ~Map();
void shoot(Field field)
{
//here is empty body of function
}
};
.
#ifdef IMAP_EXPORTS
#define IMAP_API __declspec(dllexport)
#else
#define IMAP_API __declspec(dllimport)
#endif
class IMap :
public Map
{
public:
IMAP_API IMap() {}
IMAP_API virtual ~IMap() {}
IMAP_API void shoot(Field field)
{
Map::shoot(field);
}
};
.
It's weird. It looks like it was missing copying constructor but I do not have any pointers in Field. Only automatic variables x and y. Do you have any tips to resolve this fancy error?
You have to export the whole class with IFIELD_API - otherwise the compiler-generated functions are not visible outside the shared library and you will get linker errors.

Implementing functions outside of sub class causing unknown error

I am trying to write a basic gui library in c++ and i am having problems with seemingly basic inheritence. I have a base class Component here delcared in Component.h
class Component
{
public:
virtual void add(Component &c);
virtual void remove(Component &c);
virtual void setBounds(int x, int y, int width, int height);
virtual void setLocation(int x, int y);
virtual void setSize(int width, int height);
virtual void setVisible(bool b);
};
I also have a subclass frame declared in the same header shown here
class Frame : public Component
{
private:
char* ftitle;
HWND* hwnd;
public:
Frame();
Frame(char* title);
void add(Component &c);
void remove(Component &c);
void setBounds(int x, int y, int width, int height);
void setLocation(int x, int y);
void setSize(int width, int height);
void setVisible(bool b);
void setTitle(char* title);
};
And I implement this classes functions in another file named Frame.cpp shown here
#include "Component.h"
Frame::Frame()
{
Frame("");
}
Frame::Frame(char* title)
{
ftitle = title;
*hwnd = CreateWindow("static", title, WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, NULL, NULL, GetModuleHandle(NULL), NULL);
}
void Frame::setVisible(bool visible)
{
if(visible)
{
ShowWindow(*hwnd, SW_SHOW);
}
else
{
ShowWindow(*hwnd, SW_HIDE);
}
}
void Frame::add(Component &c){}
void Frame::remove(Component &c){}
void Frame::setBounds(int x, int y, int width, int height){}
void Frame::setLocation(int x, int y){}
void Frame::setSize(int width, int height){}
void Frame::setTitle(char* title){}
However when I try to compile and build the project i get several errors shown like this
1>------ Build started: Project: GUI, Configuration: Debug Win32 ------
1> Frame.cpp
1> Generating Code...
1> Compiling...
1> Main.cpp
1> Generating Code...
1>Frame.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Component::add(class Component &)" (?add#Component##UAEXAAV1##Z)
1>Frame.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Component::remove(class Component &)" (?remove#Component##UAEXAAV1##Z)
1>Frame.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Component::setBounds(int,int,int,int)" (?setBounds#Component##UAEXHHHH#Z)
1>Frame.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Component::setLocation(int,int)" (?setLocation#Component##UAEXHH#Z)
1>Frame.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Component::setSize(int,int)" (?setSize#Component##UAEXHH#Z)
1>Frame.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Component::setVisible(bool)" (?setVisible#Component##UAEX_N#Z)
1>C:\Users\Owner\Documents\Visual Studio 2012\Projects\GUI\Debug\GUI.exe : fatal error LNK1120: 6 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
The linker is complaining about a lack of implementations for your Component class methods, because they are not pure virtual. You can fix this by making them pure virtual:
virtual void add(Component &c) = 0;
and so on.
Or alternatively, provide implementations.
Note that you should also give Component a virtual destructor.

error LNK2019: unresolved external symbol in derived class

The error occurred when I called a constructor of a derived class in another project. I omitted some details in the code. I am using Visual Studio 2012.
-Base/derived classes and the test file are in two different projects. Base/derived classes can be compiled without problems.
-The Test project can be compiled successfully when comment the constructor line.
-Test.cpp plays well with other constructor in the DerivationFunction file.
// Test.cpp
#include "DerivationFunction.h"
Child con(123, 123); // error LNK2019: unresolved external symbol "public: __thiscall Child::Child(unsigned short,unsigned int)" (??Child##QAE#GI#Z) referenced in function _main
The header file of base class and derived class:
// DerivationFunction.h
class Base
{
public:
virtual void AppendEnums() = 0;
static int CopyBuffer();
uint16 GetFeatureID();
protected:
uint16 baseValue;
static int Copy();
};
// Child class
class Child : public Base
{
public:
uint32 childValue;
Child(uint16 featureID, uint32 value);
void AppendEnums();
};
The source file:
// DerivationFunction.cpp
int Base::CopyBuffer()
{
return 0;
}
uint16 Base::GetFeatureID()
{
return baseValue;
}
int Base::Copy()
{
return 0;
}
// Child class
Child::Child(uint16 featureID, uint32 value)
{
baseValue = featureID;
childValue = value;
}
void Child::AppendEnums()
{
}
The simplest answer is that you haven't built and included the implementation file in with your main and hence the linker cannot find the code for the Child constructor. Look in the MSDN help for that particular error code and check all of the possibilities there.
If you want to use these classes in another project then you either include the whole sources (headers and cpp files) and build them, or export them from a DLL project and import them in the other project(s).

error LNK2019 unresolved external symbol virtual class

I know this question was asked several time, but i don't find how to resolve it.
I get this error when i'm trying to build my project:
error LNK2019: unresolved external symbol "public: virtual __thiscall IGameState::~IGameState(void)" (??1IGameState##UAE#XZ) in function "public: virtual __thiscall MenuState::~MenuState(void)" (??1MenuState##UAE#XZ)
Here is my code:
IGameState.h
class IGameState
{
public:
virtual ~IGameState();
virtual void update() = 0;
virtual void render() = 0;
};
MenuState.h
#include "IGameState.h"
class MenuState : public IGameState
{
public:
MenuState();
~MenuState();
void update();
void render();
};
MenuState.cpp
#include "MenuState.h"
#pragma region Constructor
MenuState::MenuState() {
}
MenuState::~MenuState() {
}
#pragma endregion
void MenuState::render() {
}
void MenuState::update() {
}
What's wrong with the destructor?
Thanks.
The error message tells you that's a link error, because you haven't implemented ~IGameState(),
Try add below code:
class IGameState
{
public:
virtual ~IGameState() {}
//^^^^ define it
virtual void update() = 0;
virtual void render() = 0;
};