c++ unresolved external symbol when trying to compile program [duplicate] - c++

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 9 years ago.
When trying to compile my program this error shows up:
Error 1 error LNK2001: unresolved external symbol "public: static class sf::Texture TextureManager::texture" (?texture#TextureManager##2VTexture#sf##A)
This is my code:
main.cpp:
int main()
{
TextureManager::Initialize();
}
TextureManager.h:
#include <SFML\Graphics.hpp>
using namespace sf;
class TextureManager
{
public:
static Texture texture;
public:
static void Initialize();
};
TextureManager.cpp:
#include <SFML\Graphics.hpp>
#include <iostream>
#include "TextureManager.h"
using namespace sf;
void TextureManager::Initialize()
{
if(!texture.loadFromFile("Textures\\Blocks\\Texture.png"))
{
std::cout << "Error!";
}
else
{
std::cout << "Sucess!";
}
}
I've tried searching for any solutions (including this site) but have not found any.

When you have a static member in C++, you should define it in your .cpp :
static Texture Texture::texture;
This is because static members must be defined in exactly one translation unit, in order to not violate the One-Definition Rule.
You can do it at the top of your TextureManager.cpp:
#include <SFML\Graphics.hpp>
#include <iostream>
#include "TextureManager.h"
using namespace sf;
static Texture Texture::texture; // <-
void TextureManager::Initialize()
{
}

Related

Unresolved external symbol error using uint16_t c++ [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 2 years ago.
endianness.cpp
#include "endianness.h"
#include <cstdint>
using namespace io;
void switch_endianness(uint16_t* n)
{
*n = (*n >> 8) | (*n << 8);
}
void switch_endianness(uint32_t* n)
{
...
}
void switch_endianness(uint64_t* n)
{
...
}
endianness.h
#ifndef ENDIANNESS_H
#define ENDIANNESS_H
#include <cstdint>
namespace io
{
void switch_endianness(uint16_t* n);
void switch_endianness(uint32_t* n);
void switch_endianness(uint64_t* n);
}
#endif
Trying to test out my switch_endianness function in app.cpp, I get an unresolved symbol error:
LNK2019 unresolved external symbol "void __cdecl io::switch_endianness(unsigned short *)" (?switch_endianness#io##YAXPEAG#Z) referenced in function main
app.cpp
#ifndef TEST_BUILD
#include <iostream>
#include "io/endianness.h"
int main(int argn, char** argv)
{
std::uint16_t y = 0x0000;
io::switch_endianness(&y);
std::cout << y;
}
#endif
How I understand and read thus far, its a linking/reference problem. I think my code is fine and should compile and run as intended, I did 'include in project' to my endianness files, perhaps there is something trivial I'm missing or doing wrong with referencing? I really can't seem to solve this.
In my endianness.cpp file I changed the function declarations to include the folder directory it was in and now it works.. (As it was complaining about this in the header file not being able to find function definition)
void io::switch_endianness(uint16_t* n)
{
...
}

Linker error LNK2019 and LNK1120 [duplicate]

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 7 years ago.
I know this problem is well known, but none of the solutions work for me. I know a popular cause of this error is the compiler can't find the definition of a function in any of the source files, but I have defined the function them.
I am using Visual studio 2015 community.
Form.h
#pragma once
template<typename T>
class Form
{
public:
void GenerateForm(T i);
};
Form.cpp
#include "stdafx.h"
#include "Form.h"
template<typename T>
void Form<T>::GenerateForm(T i)
{
std::cout << i << endl;
}
Main.cpp
#include "stdafx.h"
#include "Form.h"
int main()
{
Form<int> f;
f.GenerateForm(12);
return 0;
}
Error:
PrimeForm.obj : error LNK2019: unresolved external symbol "public: void __thiscall Formula<double>::GenerateForm(int)" (?GenerateForm#?$Formula#N##QAEXH#Z) referenced in function _main
C:\Users\John\Dropbox\Visual Studio 2015\PrimeForm\Debug\PrimeForm.exe : fatal error LNK1120: 1 unresolved externals
When you try to compile form.cpp the compiler doesn't know what type T will be. Therefore it won't be able to compile this as an object file to be linked with your compiled main.cpp object file.
You'll need to include all of the declarations and definitions of a templated class to the files that need it (in this case your main.cpp file).
This can be simply done as follows:
Form.h
#pragma once
template<typename T>
class Form
{
public:
void GenerateForm(T i);
};
#include "Form.template" /* Note include Form.template here */
Form.template
#include "stdafx.h"
/* Don't include form.h in this file */
template<typename T>
void Form<T>::GenerateForm(T i)
{
std::cout << i << std::endl;
}
main.cpp
#include "stdafx.h"
#include "Form.h" /* including Form.h will include Form.template as well */
int main()
{
Form<int> f; /* Compiler now knows to instantiate a Form class with type Int as the template parameter */
f.GenerateForm(12);
return 0;
}
Note the main difference is that you don't include "Form.h" in Form.template but include "Form.template" at the bottom of Form.h
It is better practice to use the ".template" file ending for templated class implementation files.

error LNK2019: unresolved external symbol "public: void __thiscall Button::ButtonInit" [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
I've been going through a C++/SFML tutorial (http://www.gamefromscratch.com/page/Game-From-Scratch-CPP-Edition.aspx) and, having reached the end, started altering the code to try out various things and get more comfortable both with C++ and SFML.
For the menu screen, I decided to create an object for buttons. To this end I created Button.cpp and Button.h, then linked to Button.h in the MainMenu.h file. I added Button button_play as a public member of class MainMenu, however when I call a Button function (for example: button_play.ButtonInit("new-game");), I receive the error: error LNK2019: unresolved external symbol "public: void __thiscall Button::ButtonInit(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?ButtonInit#Button##QAEXV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) referenced in function "public: enum MainMenu::MenuResult __thiscall MainMenu::Show(class sf::RenderWindow &)" (?Show#MainMenu##QAE?AW4MenuResult#1#AAVRenderWindow#sf###Z)
I've done a lot of searching around this, and most of the answers I've found revolve around not implementing class member functions correctly, however as far as I can tell I am doing it correctly. I am, however, very new to C++, so it's possible that I'm just missing something.
Here's my code:
MainMenu.h
#pragma once
#include "SFML\Window.hpp"
#include "SFML\Graphics.hpp"
#include "GameObjectManager.h"
#include "Button.h"
#include <list>
class MainMenu
{
public:
MainMenu(){};
~MainMenu() {};
enum MenuResult { Nothing, Exit, Play };
const static GameObjectManager& GetGameObjectManager();
struct MenuItem
{
public:
sf::Rect<int> rect;
MenuResult action;
};
MenuResult Show(sf::RenderWindow& window);
static GameObjectManager _gameObjectManager;
Button button_play;
private:
MenuResult GetMenuResponse(sf::RenderWindow& window);
MenuResult HandleClick(int x, int y);
std::list<MenuItem> _menuItems;
};
MainMenu.cpp (this is quite long; I've only included the function that calls ButtonInit() and the function that Show() returns - if you need to see more, let me know and I can include the rest of the code for this file)
#include "stdafx.h"
#include "MainMenu.h"
#include "ServiceLocator.h"
#include "Button.h"
MainMenu::MenuResult MainMenu::Show(sf::RenderWindow& window)
{
button_play.ButtonInit("new-game");
return GetMenuResponse(window);
}
MainMenu::MenuResult MainMenu::GetMenuResponse(sf::RenderWindow& window)
{
sf::Event menuEvent;
while(42 != 43)
{
while(window.pollEvent(menuEvent))
{
if(menuEvent.type == sf::Event::MouseMoved)
{
button_play.Update(window);
}
if(menuEvent.type == sf::Event::MouseButtonPressed)
{
if(ServiceLocator::GetAudio()->IsSongPlaying())
{
ServiceLocator::GetAudio()->StopAllSounds();
}
return HandleClick(menuEvent.mouseButton.x,menuEvent.mouseButton.y);
}
if(menuEvent.type == sf::Event::Closed)
{
return Exit;
}
}
}
}
Button.h
#pragma once
class Button
{
public:
Button() {};
~Button() {};
void ButtonInit(std::string name);
void Update(sf::RenderWindow & rw);
};
Button.cpp
#include "StdAfx.h"
#include "Button.h"
void Button::ButtonInit(std::string name)
{
}
void Button::Update(sf::RenderWindow & rw)
{
}
stdafx.h (probably don't need to see this, but just in case)
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here
#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/Audio.hpp>
#include <map>
#include <iostream>
#include <cassert>
#include <string>
Any help would be appreciated.
I assume, you have both classes in the same project.
The linker-message tells you, that the linker does not find a fitting function definition.
So my guess would be ... the linker cannot find a fitting overload of the function. "new-game" is a const char* and it is not a std::string.
a) change your method signature to
void ButtonInit(const char* name);
or
b) call your method like:
button_play.ButtonInit(std::string("new-game"));

Static Lib using namespace leads to unresolved external

I am using VS2013 and I have a static lib project with the following header:
#pragma once
namespace StaticLibNamespace
{
void foo( void );
}
Then the function is defined in the cpp as follows:
#include "stdafx.h"
#include "StaticLibHeader.h"
using namespace StaticLibNamespace;
void foo( void )
{
;
}
In my simple console app, I include the reference to StaticLibNameSpaceTest.lib and my main function is the following:
#include "stdafx.h"
#include "..\StaticLibNamespaceTest\StaticLibHeader.h"
int _tmain(int argc, _TCHAR* argv[])
{
StaticLibNamespace::foo();
return 0;
}
If I try and compile this I get the following error:
NamespaceTest.obj : error LNK2019: unresolved external symbol "void __cdecl StaticLibNamespace::foo(void)" (?foo#StaticLibNamespace##YAXXZ) referenced in function _wmain
However if I change my static lib cpp file to the following everything is fine:
#include "stdafx.h"
#include "StaticLibHeader.h"
void StaticLibNamespace::foo( void )
{
;
}
I'm obviously not understanding everything going on with "using namespace" can someone please enlighten me? Thanks!
The using namespace directive changes the lookup rules for symbols when the compiler sees an unqualified name and needs to find what it refers to.
However, in your case, you are defining a new function called foo. As an unqualified name, this defines a new foo in the global namespace (assuming there wasn't already one there). When you qualify the name, you are defining StaticLibNamespace::foo as you intend.
A different solution might be:
namespace StaticLibNamespace {
void foo( void )
{
;
}
} // namespace StaticLibNamespace

C++ "unresolved external symbol" using namespace from different project

I have two projects (call them Test and Intrados). Inside Intrados, I have the following namespace:
#include "Mapper.h"
#include "Director.h"
#include "Driver.h"
#include <iostream>
#include <string>
using namespace std;
namespace IntradosMediator {
void addVehicle(string);
}
void IntradosMediator::addVehicle(string vehicleName) {
Mapper* mapper = Mapper::getInstance();
mapper->addVehicle(vehicleName);
}
From within the Intrados project, calling "IntradosMediator::Mapper(addVehicle)" works just fine; yet, in project Test, the following code produces a link error:
#include "IntradosMediator.cpp"
#include "Mapper.h"
using namespace IntradosMediator;
int main(){
IntradosMediator::addVehicle("Car X");
return 0;
}
The error is:
Test.obj : error LNK2019: unresolved external symbol "public: static class Mapper *
__cdecl Mapper::getInstance(void)" (?getInstance#Mapper##SAPAV1#XZ) referenced in
function "void __cdecl IntradosMediator::addVehicle(class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> >)"
(?addVehicle#IntradosMediator##YAXV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##
std###Z)
I've made sure to add Intrados as a reference for Test, and also included it in the Include Directories. Not sure what to do here, since I'm new to C++. Thanks in advance for any advice.
Edit:
I'm adding the Mapper code here:
//.h
#ifndef MAPPER_H
#define MAPPER_H
#include <string>
using std::string;
class Mapper {
public:
static Mapper* getInstance();
void addVehicle(string);
private:
//this is a singleton
Mapper(){};
};
#endif
//.cpp
#include "Mapper.h"
#include <vector>
#include <iostream>
#include <string>
using namespace std;
vector<string> vehicleList;
Mapper* Mapper::getInstance(){
static Mapper instance;
return &instance;
}
void
Mapper::addVehicle(string vehicleName) {
vehicleList.push_back(vehicleName);
}
The error says the linker can't find Mapper::getInstance (it seems to find your addVehicle function just fine). Might you be failing to include the library that implements "Mapper" in your link?
Could you paste your code for class Mapper?
It seems like you are missing addVehicle function in that class, which is what the compiler is complaining about.