Evil LNK2019 Error

Started by
9 comments, last by Madhed 19 years, 2 months ago
Okay, I tap out. I've been working with this for 3 hours and I have no idea what I'm doing wrong. I pretty much followed my book for breaking up the file. Anyhow, I'm using Visual C++ .net Standard and I'm getting the following compile error: Homebrew RPG error LNK2019: unresolved external symbol "public: void __thiscall Character::Report(void)" (?Report@Character@@QAEXXZ) referenced in function _main I know I'm doing something incorrect with the function but I can't figure out what. Anyway, here's the source for my 3 files. My app file: #include "stdafx.h" #include "stdlib.h" #include "character.h" using namespace std; int _tmain(int argc, _TCHAR* argv[]) { Character fighter(10,14,3,7,5,6,3); fighter.Report(); //cout << fighter.m_Mp; return 0; } My character.h file #ifndef CHARACTER_H #define CHARACTER_H class Character // Declares class for Basic character of the game { public: int m_Hp; int m_Mp; int m_Attack; int m_Defense; int m_Intelligence; int m_Agility; int m_Luck; Character(int hp, int mp, int attack, int defense, int intelligence, int agility, int luck); //Prototype for contsructor void Report(void); //Member function }; Character::Character(int hp, int mp, int attack, int defense, int intelligence, int agility, int luck) // Persona's Constructor { m_Hp = hp; m_Mp = mp; m_Attack = attack; m_Defense = defense; m_Intelligence = intelligence; m_Agility = agility; m_Luck = luck; } #endif And my character.cpp file //Character.cpp //Implementation file #include "stdafx.h" #include "stdlib.h" #include "character.h" using namespace std; void Character::Report(void) { cout << "Created a new character" << endl << "HP: " << m_Hp << endl << "MP: " << m_Mp << endl << "Attack: " << m_Attack << endl << "Defense: " << m_Defense << endl << "Intelligence: " << m_Intelligence << endl << "Agility: " << m_Agility << endl << "Luck: " << m_Luck << endl; } Save me please! :)
Advertisement
Hm, I don't really think that's it, but have you added the character.cpp file to your workspace?

The link error means:
"Hey, I know the Character::Report() function must be somewhere but I can't find it!"

So either the function is missing, you have mis-spelled it or you have it defined and declared with different parameters and/or return values.
Aside from what Madhed said...

Here's what I found:

#include "stdlib.h"

is that supposed to be
#include <stdlib.h> ? (or actually, the C++ file for this is <cstdlib>

secondly, your constructor shouldn't be in the header file, it should be in the implementation file. I know this isn't the trouble your having, but it's an issue -I- get when trying to compile your code ;) Otherwise it was getting linked twice and there's a linker error regarding multiple definitions.

After those two changes, it compiled fine for me though. Hope that helps =)
Madhead, when I do that, I get this instead: Homebrew RPG error LNK2005: "public: __thiscall Character::Character(int,int,int,int,int,int,int)" (??0Character@@QAE@HHHHHHH@Z) already defined in Homebrew RPG.obj
brinmalice,

Yep, thats what should happen with how your code is written. Get that constructor out of your header file and into your manipulation file ;)

This needs to be in character.cpp!!
Character::Character(int hp, int mp, int attack, int defense, int intelligence,int agility, int luck) // Persona's Constructor{m_Hp = hp;m_Mp = mp;m_Attack = attack;m_Defense = defense;m_Intelligence = intelligence;m_Agility = agility;m_Luck = luck;}
Quote:Original post by Rhalin
Aside from what Madhed said...

Here's what I found:

#include "stdlib.h"

is that supposed to be
#include <stdlib.h> ? (or actually, the C++ file for this is <cstdlib>

secondly, your constructor shouldn't be in the header file, it should be in the implementation file. I know this isn't the trouble your having, but it's an issue -I- get when trying to compile your code ;) Otherwise it was getting linked twice and there's a linker error regarding multiple definitions.

After those two changes, it compiled fine for me though. Hope that helps =)


Rhalin, you're a genious. I think it was a combination of things. Once I added the files to vis c++, changed the library, then moved the constructor it worked fine. Weird part was I could get access to the class without adding it to vis c++. Just couldn't get the func to work.
Quote:Madhead, when I do that, I get this instead: Homebrew RPG error LNK2005: "public: __thiscall Character::Character(int,int,int,int,int,int,int)" (??0Character@@QAE@HHHHHHH@Z) already defined in Homebrew RPG.obj


???Hm............ what did you do? :D

Do it like this:

//app.cpp#include "stdafx.h"#include <cstdlib>#include "character.h"using namespace std;int _tmain(int argc, _TCHAR* argv[]){Character fighter(10,14,3,7,5,6,3);fighter.Report();//cout << fighter.m_Mp;return 0;}


//character.h#ifndef CHARACTER_H#define CHARACTER_Hclass Character // Declares class for Basic character of the game{public:int m_Hp;int m_Mp;int m_Attack;int m_Defense;int m_Intelligence;int m_Agility;int m_Luck;Character(int hp, int mp, int attack, int defense, int intelligence,int agility, int luck); //Prototype for contsructorvoid Report(void); //Member function};#endif


//Character.cpp//Implementation file#include "stdafx.h"#include <cstdlib>#include "character.h"using namespace std;Character::Character(int hp, int mp, int attack, int defense, int intelligence,int agility, int luck) // Persona's Constructor{m_Hp = hp;m_Mp = mp;m_Attack = attack;m_Defense = defense;m_Intelligence = intelligence;m_Agility = agility;m_Luck = luck;}void Character::Report(void){cout << "Created a new character" << endl<< "HP: " << m_Hp << endl<< "MP: " << m_Mp << endl<< "Attack: " << m_Attack << endl<< "Defense: " << m_Defense << endl<< "Intelligence: " << m_Intelligence << endl<< "Agility: " << m_Agility << endl<< "Luck: " << m_Luck << endl;}
Quote:Weird part was I could get access to the class without adding it to vis c++. Just couldn't get the func to work.


this is not weird at all. At compile time the compiler doesn't need to know
whether an object exists or not. it just assumes it's there.
Later when linking all .obj files together (one .obj for each .cpp)
The linker doesn't find the object and it spits out an error.

;)

Cya next time
just a brief explanation of these nonsense linker errors in the simplest way I can think of (althought maybe not -entirely- accurate, hopefully easy to understand)...

The compiler is going to go through your files one at a time turning each one into intermediate code. Everytime a .h file is included, its contents get loaded into that intermediate object. The header guards (#ifndef things) keep the compilier from including header declarations multiple times into the intermediate file. The problem comes with functions and variables. If these are in a header that is included in multiple files in your project, they end up in more than one intermediate file, and when the linker goes through, it finds these functions in more than one intermediate and gives you an error. For this reason, you need to keep the function parts of your classes in the implementation file. Also, any global variables defined you should be using externs for.... but if you dont have to worry about that, dont right now, one thing at a time. ;)

Hope this helps a little!
Thanks for the quick help guys. I knew it was something stupid. I was actually following the examples from chapter 10 of this book:

http://www.gamedev.net/columns/books/bookdetails.asp?productid=379

It never really said what to do with the constructor because the class they use in the example doesn't have one.

This topic is closed to new replies.

Advertisement