Problems with headers and linker errors (new to C++) - c++

I'm new to c++ and I'm having some trouble with making a header file. The exact error I'm getting is
obj.obj : error LNK2019: unresolved external symbol "float * __cdecl getVertices(class std::basic_string,class std::allocator >,int,float *)" (?getVertices##YAPAMV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##HPAM#Z) referenced in function "struct ObjModel __cdecl importObj(void)" (?importObj##YA?AUObjModel##XZ)
The bugs/solutions I'm seeing seem much more complicated that what I'm doing. Here's my header, which I suspect is wrong.
//obj.h
#ifndef OBJ_H_INCLUDED
#define OBJ_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
struct ObjVertex {
float x, y, z;
};
struct ObjTriangle {
int Vertex[3];
int Normal[3];
};
struct ObjModel {
int NumVertex, NumNormal, NumTexCoord, NumTriangle;
ObjVertex *VertexArray;
ObjVertex *NormalArray;
ObjTriangle *TriangleArray;
};
//function prototypes
float* getVertices(string buf, int i, float* ret);
ObjModel importObj();
char* subString(char* buf, int b, int e);
#endif
I've just started in C++ but I have experience in Java and C, so it's probably an issue with me not knowing some C++ specific thing.

There is no implementation for float* getVertices(string buf, int i, float* ret); hence you get a linker error.

You must attach module where getVertices is declared to the project.

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)
{
...
}

error LNK2005: quest_tree::enter_one(class quest_tree::quest_node * &,class std::basic_string<char,struct std::char_traits<char>

I've seen many posts on LNK2005 error, but decided to ask my own anyway.
Here is the error code:
1>setup_quest_tree.obj : error LNK2005: "private: void __thiscall quest_tree::enter_one(class quest_tree::quest_node * &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?enter_one#quest_tree##AAEXAAPAVquest_node#1#ABV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) already defined in mainFunction.obj
1>setup_quest_tree.obj : error LNK2005: "void __cdecl setup_quest_tree(void)" (?setup_quest_tree##YAXXZ) already defined in mainFunction.obj
1>C:\Users\Timothy\Documents\Visual Studio 2008\Projects\ttbag\Debug\TTBAG.exe : fatal error LNK1169: one or more multiply defined symbols found
I'm trying to get the program to compile but am running into linker errors while doing so, probably because I've included quest_tree.h twice, but when I got rid of one of the declarations of quest_tree.h in setup_quest_tree.cpp I run into this error:
1>c:\users\timothy\documents\visual studio 2008\projects\ttbag\ttbag\setup_quest_tree.cpp(8) : error C2065: 'quest_tree' : undeclared identifier
There are many files so I am only including the ones for my project that are related to the error.
setup_quest_tree.cpp:
#ifndef SETUP_QUEST_NODES_CPP
#define SETUP_QUEST_NODES_CPP
#include <string>
#include "quest_tree.h"
void setup_quest_tree() {
quest_tree quest_tree_obj; //start out with two quest nodes
std::string welcome_message = "debug-welcome message";
quest_tree_obj.enter(welcome_message);
}
#endif
setup_quest_tree.h:
#ifndef SETUP_QUEST_TREE_H
#define SETUP_QUEST_TREE_H
#include "quest_tree.h"
#include "setup_quest_tree.cpp"
//function declarations
void setup_quest_tree (quest_tree &quest_tree_obj);
#endif /* SETUP_QUEST_TREE_H */
mainFunction.cpp (just the include statements):
#define DEBUG_LINES_ON
#include <iostream>
#include <fstream>
#include <time.h>
#include "weather.h"
#include "item.h"
#include "map.h"
#include "person.h"
#include "location.h"
#include "bag.h"
#include "equipped_items.h"
#include "global_vars.h"
#include "setup_quest_tree.h"
int main() { ...
quest_tree.h:
#ifndef QUEST_TREE_H
#define QUEST_TREE_H
#include <string>
#include <cstdlib>
class quest_tree {
private:
// the basic node of the tree. Do way to read from file?
class quest_node {
private:
quest_node *quest_nodes; // pointer to array of quests that activate upon quest activation
public:
//std::string word; // we will replace this with our own data variable
std::string note_to_player; //note that is shown upon quest activation
/*
quest_node(){ // default constructor
note_to_player = "";
}
*/
quest_node(short int num_nodes = 2){
quest_nodes = new quest_node[num_nodes]; // problem: not declared in quest_tree but rather in quest_node
note_to_player = "";
}
friend class quest_tree;
};
// the top of the tree
quest_node * root;
// Enter a new node into the tree or sub-tree
void enter_one(quest_node *&node, const std::string& note_to_player);
public:
quest_tree() {root = NULL;} // constructor
// Add a new note_to_player to our tree
void enter(std::string& note_to_player) {
enter_one(root, note_to_player);
}
};
void quest_tree::enter_one(quest_node *&new_node, const std::string& note_to_player)
{
// see if we have reached the end
if (new_node == NULL) {
new_node = new quest_node;
for (short int index = 0; index < (sizeof(new_node->quest_nodes)/sizeof(new_node->quest_nodes[0])); index++) { // initialize quest_nodes
new_node->quest_nodes[index] = NULL;
}
new_node->note_to_player = note_to_player;
}
if (new_node->note_to_player == note_to_player)
return;
/*
if (new_node->note_to_player < note_to_player)
enter_one(new_node->right, word);
else
enter_one(new_node->left, word)
*/
}
#endif /* QUEST_TREE_H */
You have included the implementation in the setup_quest_tree.h header file
#include "setup_quest_tree.cpp"
and included it in several translation units.
To fix this, at least in setup_quest_tree.cpp just include the declarations from setup_quest_tree.h, and remove that #include "setup_quest_tree.cpp" statement from setup_quest_tree.h should fix your linker errors.
You have to provide exclusively one definition (implementation) for your class (see also this answer for "Is is a good practice to put the definition of C++ classes into the header file?").
If you put it there, just since you don't know how to add the setup_quest_tree.cpp to your program, check this Q&A please to learn more about the linking process.
Here's the relevant section from the current c++ standard
3.2 One definition rule [basic.def.odr]
1 No translation unit shall contain more than one definition of any variable, function, class type, enumeration
type, or template.

Really basic class won't build

Can someone please tell me what is wrong with this code? I don't get it at all..
I am trying to generate an object out of class "T_Tsunami".
The errors I get are:
"error LNK2019: unresolved external symbol "public: __thiscall T_Tsunami::~T_Tsunami(void)" (??1T_Tsunami##QAE#XZ) referenced in function _main"
and
"fatal error LNK1120: 1 unresolved externals".
Header:
#include <string>
using std::string;
#include<vector>
class T_Tsunami
{
public:
// Constructor with default arguments
T_Tsunami (const int nl = 100, const string="T_Tsunami");
~T_Tsunami(); // destructor
void setNL(int);
void setNaam(string);
private:
string Naam;
int Golf_NL;
};
cpp-file:
#include <vector>
#include <iostream>
#include <fstream>
#include <cmath>
#include "T_Tsunami.h"
T_Tsunami::T_Tsunami (const int nl, const string nieuwe_naam)
{
setNL(nl);
setNaam(nieuwe_naam);
}
void T_Tsunami::setNL(int nl)
{
Golf_NL = nl;
}
void T_Tsunami::setNaam(string nieuwe_naam)
{
Naam = nieuwe_naam;
}
Main:
#include <vector>
#include <iostream>
#include <fstream>
#include <cmath>
#include"T_Tsunami.h"
int main() {
T_Tsunami myTsunami;
}
Also I don't know if I need to put a return statement in the main, I did try that but it doesn't solve my problem.
You did not define the destructor, such as:
T_Tsunami::~T_Tsunami()
{
}

Visual Studio C++ 2010 in-project link error

I have a multi-file project in VSC++2010, but for some reason it won't link some of them properly.
For example, I have CParser.h and CParser.cpp . CParser.h is just some function declarations:
#pragma once
#include <string>
void parseArg(int argc, char* argv[], GVar gv);
void parseCfg(string cfg, GVar gv)
CParser.cpp just contains implementations:
#include <cstdio>
#include <fstream>
#include <cstring>
#include <string>
#include "_GlobalVar.h" //defines GVar, not relevant
#include "CParser.h"
void parseArg(int argc, char* argv[], GVar &gv) {
/*not really relevant*/
}
And the error:
main.obj : error LNK2019: unresolved external symbol "void __cdecl
parseArg(int,char * * const,class GVar)"
(?parseArg##YAXHQAPADVGVar###Z) referenced in function _SDL_main
Edit:
There's also this other problem:
template<class T>
void RDAMHandler<T>::clean() {
long i;
while(!avtick.empty())
avtick.pop();
for(i = v.size() - 1; i >= 0; i--) {
delete all[i];
all.pop_back();
v.pop_back();
}
}
And the declaration:
template<class T>
class RDAMHandler {
vector<T*> all;
priority_queue<long> avtick;
vector<bool> v;
public:
T &operator[](long x);
long insert(T &x);
void del(long x);
void clean();
};
I don't see any difference here; what is the problem?
Edit edit: And error
main.obj : error LNK2019: unresolved external symbol "public: void
__thiscall RDAMHandler::clean(void)" (?clean#?$RDAMHandler#USDL_Surface####QAEXXZ) referenced in function
"void __cdecl cleanUp(class GVar)" (?cleanUp##YAXVGVar###Z)
In CParser.cpp
I think You have to use statement
void CParser::parseArg(int argc, char* argv[], GVar &gv)
instead of
void parseArg(int argc, char* argv[], GVar &gv) in CParser.cpp file
And In CParser.h
The declaration should be changed to void parseArg(int argc, char* argv[], GVar &gv);
And For Next Error
For Reference Please Go through this
1. Template using class
Hope this will help you.
They're two different overloads - the declaration in the header has GVar gv, while the definition in the .cpp file has GVar &gv. One of these is probably a typo.

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.

Categories