In such form...
#ifndef UNICODE
#define UNICODE
#endif
#include <Windows.h>
#include <iostream>
class A
{
public:
void makeFoo(TCHAR* output)
{
wcscpy(outputBuffer,TEXT("Hello world ♥"));
}
private:
static const int MAX_OUTPUT_SIZE=2000;
static TCHAR outputBuffer[MAX_OUTPUT_SIZE];
};
int main()
{
TCHAR string[255];
A example;
example.makeFoo(string);
MessageBox(0,string,0,0);
system("Pause");
return 0;
}
... we have a
linking error!
1>main.obj : error LNK2001: unresolved external symbol "private:
static wchar_t * A::outputBuffer" (?outputBuffer#A##0PA_WA)
The linker error occurs because you have not provided a definition for the A::outputBuffer anywhere. Fix this by writing this in file scope:
TCHAR A::outputBuffer[A::MAX_OUTPUT_SIZE];
The value of string is unexpected because that buffer is uninitialized; makeFoo does nothing with its argument, and you do not initialize the buffer manually. Therefore it can contain anything at all ("garbage").
Add:
TCHAR A::outputBuffer[A::MAX_OUTPUT_SIZE];
above main().
Related
I've been struggling to find why my linker gets an unresolved external symbol error. The error looks like this:
Error
LNK2019
unresolved external symbol "public: __thiscall Shader::Shader(char const *)" (??0Shader##QAE#PBD#Z) referenced in function "public: __thiscall GridWorldGPGPU::GridWorldGPGPU(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,unsigned int)" (??0GridWorldGPGPU##QAE#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##I#Z)
DV2556_Project
grid_world_GPGPU.obj
1
As far as I understand it it has something to do with that my linker finds the declaration of the Shader::Shader(char const *)-function but cannot find the definition. I have been staring at this for hours and cannot figure out why the linker becomes sad.
grid_world_GPGPU.h:
#ifndef GRID_WORLD_GPGPU_H
#define GRID_WORLD_GPGPU_H
#include "grid_world.h"
#include <../swift_open_gl.h>
class GridWorldGPGPU : public GridWorld {
private:
Shader* compute_shader_ = nullptr;
public:
GridWorldGPGPU(std::string in_path_shader, unsigned int in_side = 1);
};
#endif // !GRID_WORLD_GPGPU_H
grid_world_GPGPU.cpp:
GridWorldGPGPU::GridWorldGPGPU(std::string in_path_shader, unsigned int in_side)
: GridWorld(in_side) {
this->compute_shader_ = new Shader(in_path_shader.c_str());
}
The Shader-class is defined in the swift_open_gl.h file:
#ifndef SWIFT_OPEN_GL_H
#define SWIFT_OPEN_GL_H
#include <glad/glad.h>
#include <GLFW/glfw3.h>
class Shader {
public:
Shader(const char* cs_path);
};
#endif // !SWIFT_OPEN_GL_H
And swift_open_gl.cpp has this:
#include "..\swift_open_gl.h"
inline Shader::Shader(const char * cs_path) {
//Do stuff
}
I've tried with and without the inline (Visual Studio added it when I tried moving the function definition between the .h-file and a .cpp-file, so I decided to try it) and i have verified that the #include <../swift_open_gl.h> doesn't occur anywhere else in the project than the files listed above.
An extra set of eyes to look over this would be appreciated!
Provide default constructor of the class as well.
class Shader {
public:
Shader(){} // default constructor
Shader(const char* cs_path);
};
Dont use inline in Shader::Shader(const char* cs_path){} definition
See code below. There's something wrong with it, because the linker is complaining it can't find the Memory's functions, but I can't figure out why.
memory.h
#pragma once
#include "includes.h" //it just includes other strandard headers.
class MemoryUnit
{
public:
MemoryUnit() {}
virtual int getValue() = 0;
virtual int getSize() = 0;
virtual void setValue(int) = 0;
virtual ~MemoryUnit() {};
};
class Byte : public MemoryUnit
{
int value;
public:
static int size;
Byte(int byte) :value(byte) {};
int getSize() { return size; }
int getValue() { return value; };
void setValue(int byte) { value = byte; }
~Byte() {};
};
namespace Memory
{
extern int size;
extern MemoryUnit** map;
void checkAddress(int address);
int read(int adress);
MemoryUnit* getOperation(int address);
void write(int adress, MemoryUnit* data);
void writeByte(int adress, int data);
}
memory.cpp
#include "includes.h"
#include "memory.h"
#include "simulator.h" // it contains only externed constants.
namespace Memory
{
int size = 0;
MemoryUnit** map = NULL;
inline MemoryUnit* getOperation(int address)
{
return map[address];
}
inline void checkAddress(int address)
{
if (address < 0 || address >= MAX_MEMORY_SIZE)
throw std::out_of_range("Invalid memory address.");
}
inline int read(int address)
{
checkAddress(address);
return map[address]->getValue();
}
inline void write(int address, MemoryUnit* data)
{
checkAddress(address);
delete map[address];
map[address] = data;
}
inline void writeByte(int address, int data)
{
checkAddress(address);
map[address]->setValue(data);
}
}
Everywhere the class/namespace memory.h declares is includes memory.h. Is here anything wrong in the code below?
Edit:
I'm using Visual Studio 2015.
Errors I got when building the project:
LNK1120 5 unresolved externals simulator.exe
LNK2019 unresolved external symbol "void __cdecl Memory::writeByte(int,int)" referenced in function "void __cdecl ALU::setFlags(int)" alu.obj
LNK2001 unresolved external symbol "void __cdecl Memory::writeByte(int,int)" cu.obj
LNK2019 unresolved external symbol "class MemoryUnit * __cdecl Memory::getOperation(int)" referenced in function "void __cdecl CU::run(void)" cu.obj
LNK2001 unresolved external symbol "void __cdecl Memory::writeByte(int,int)" helpers.obj
LNK2019 unresolved external symbol "void __cdecl Memory::write(int,class MemoryUnit *)" referenced in function "void __cdecl readProgramCommands(void)" helpers.obj
LNK2001 unresolved external symbol "public: virtual int __thiscall MemoryPointer::getValue(void)" helpers.obj
LNK2001 unresolved external symbol "public: virtual int __thiscall IndirectMemoryPointer::getAddress(void)" helpers.obj
LNK2001 unresolved external symbol "void __cdecl Memory::writeByte(int,int)" main.obj
alu.h and alu.cpp for the first error:
//alu.h
#pragma once
#include "includes.h"
#include "operation.h"
namespace ALU
{
int operation(Operation* op);
void setFlags(int result);
}
//alu.cpp
#include "includes.h"
#include "simulator.h"
#include "alu.h"
#include "memory.h"
#include "operation.h"
namespace ALU
{
int operation(Operation* operation)
{
// ...
setFlags(result);
return result;
}
inline void setFlags(int result)
{
Memory::writeByte(FLAG_Z, result == 0);
// ...
}
}
You need to put the inline function definition inside your header file (they both must appear in every translation unit where they are used), you can separate declaration and definition but both must be in the header file. Also they must be declared as inline.
N4140 dcl.fct.spec 7.1.2.4
An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly
the same definition in every case (3.2). [ Note: A call to the inline function may be encountered before its
definition appears in the translation unit. —end note ] If the definition of a function appears in a translation
unit before its first declaration as inline, the program is ill-formed.
When you're using inline functions or methods, their definitions should be visible for every source unit that uses them. You defined your inline functions in Memory.cpp, that's why you get 'unresolved' linker error.
To fix your problem you can:
Remove inline modifier and keep functions definitions in Memory.cpp.
Keep inline modifier but move functions definitions to Memory.h.
I am working on a project for school. I am aware of my circular dependency(And have read most of the resolutions here for that previously) but it works currently the way I need it to. Sadly I'm pretty sure it is also the cause of my woes. I would like to include concol.h so that it can be used with both files (I'd like to add some color to my output - not a requirement for my assignment but something I would like to do). I've tried placement of this header file in several different locations and I always get the same errors. I considered using the forward declaration like I did to work with the circular dependency but I don't think that will work with a namespace.
Errors:
1>Flight.obj : error LNK2005: "void * eku::std_con_out" (?std_con_out#eku##3PAXA) already defined in BoardingPass.obj
1>Flight.obj : error LNK2005: "bool eku::colorprotect" (?colorprotect#eku##3_NA) already defined in BoardingPass.obj
1>Flight.obj : error LNK2005: "enum eku::concol eku::textcol" (?textcol#eku##3W4concol#1#A) already defined in BoardingPass.obj
1>Flight.obj : error LNK2005: "enum eku::concol eku::backcol" (?backcol#eku##3W4concol#1#A) already defined in BoardingPass.obj
1>Flight.obj : error LNK2005: "enum eku::concol eku::deftextcol" (?deftextcol#eku##3W4concol#1#A) already defined in BoardingPass.obj
1>Flight.obj : error LNK2005: "enum eku::concol eku::defbackcol" (?defbackcol#eku##3W4concol#1#A) already defined in BoardingPass.obj
1>Source.obj : error LNK2005: "void * eku::std_con_out" (?std_con_out#eku##3PAXA) already defined in BoardingPass.obj
1>Source.obj : error LNK2005: "bool eku::colorprotect" (?colorprotect#eku##3_NA) already defined in BoardingPass.obj
1>Source.obj : error LNK2005: "enum eku::concol eku::textcol" (?textcol#eku##3W4concol#1#A) already defined in BoardingPass.obj
1>Source.obj : error LNK2005: "enum eku::concol eku::backcol" (?backcol#eku##3W4concol#1#A) already defined in BoardingPass.obj
1>Source.obj : error LNK2005: "enum eku::concol eku::deftextcol" (?deftextcol#eku##3W4concol#1#A) already defined in BoardingPass.obj
1>Source.obj : error LNK2005: "enum eku::concol eku::defbackcol" (?defbackcol#eku##3W4concol#1#A) already defined in BoardingPass.obj
1>D:\School Stuff\Fall 2015\CIST 2362 C++ II\Final - Airline Reservation System\Debug\Final - Airline Reservation System.exe : fatal error LNK1169: one or more multiply defined symbols found
Source.cpp
#include <fstream>
#include <iostream>
#include <iomanip>
#include "FlightComparators.h" //includes Flight.h
#include "LocationComparators.h"
//prototypes
//methods
Flight.h
#ifndef FLIGHT_H
#define FLIGHT_H
#ifndef BOARDINGPASS_H
#include "BoardingPass.h"
#endif
#include <algorithm>
#include <string>
#include <vector>
#include "Location.h"
#include "Validate.h"
#include "AirlineTypeA.h"
#include "AirlineTypeB.h"
class BoardingPass;
class Flight{
private:
Location *departureLoc;
Location *destinationLoc;
char departureTime[6];
char arrivalTime[6];
int number;
int freqFlyerMiles;
int curOccupancy = 0;
Airline *plane;
vector<BoardingPass*> passengers;
public:
//constructor
Flight(Location*, Location*, string, string, int, int, char type);
//getters
Location* getDepartureLoc(){ return departureLoc; }
Location* getDestinationLoc(){ return destinationLoc; }
int getFlightNumber(){ return number; }
int getFreqFlyerMiles(){ return freqFlyerMiles; }
string getDepTime(){ return departureTime; }
string getAriTime(){ return arrivalTime; }
int getCurOccupancy(){ return curOccupancy; }
Airline* getPlane(){ return plane; }
vector<BoardingPass*> getPassengerList(){ return passengers; }
bool getIsFull(){ return this->plane->getMaxPass() > curOccupancy; }
void addPass(string, string, string);
void cancelReservation(int);
void displayPassengers();
void sortPassengers();
};
#endif
BoardingPass.h
#ifndef BOARDINGPASS_H
#define BOARDINGPASS_H
#ifndef FLIGHT_H
#include "Flight.h"
#endif
#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
class Flight;
class BoardingPass{
private:
string fName;
string lName;
Flight* flight;
string seat;
public:
BoardingPass(string, string, Flight *flt, string seat);
string getFName(){ return fName; }
string getLName(){ return lName; }
string getSeat(){ return seat; }
void displayBoardingPass();
void writeBoardingPass(fstream&);
};
#endif
concol.h
#ifndef INC_EKU_IO_CONCOL
#define INC_EKU_IO_CONCOL
/*Header file to color text and background in windows console applications
Global variables - textcol,backcol,deftextcol,defbackcol,colorprotect*/
#include<windows.h>
#include<iosfwd>
namespace eku
{
#ifndef CONCOL
#define CONCOL
enum concol
{
black = 0,
dark_blue = 1,
dark_green = 2,
dark_aqua, dark_cyan = 3,
dark_red = 4,
dark_purple = 5, dark_pink = 5, dark_magenta = 5,
dark_yellow = 6,
dark_white = 7,
gray = 8,
blue = 9,
green = 10,
aqua = 11, cyan = 11,
red = 12,
purple = 13, pink = 13, magenta = 13,
yellow = 14,
white = 15
};
#endif //CONCOL
HANDLE std_con_out;
//Standard Output Handle
bool colorprotect = false;
//If colorprotect is true, background and text colors will never be the same
concol textcol, backcol, deftextcol, defbackcol;
/*textcol - current text color
backcol - current back color
deftextcol - original text color
defbackcol - original back color*/
inline void update_colors()
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(std_con_out, &csbi);
textcol = concol(csbi.wAttributes & 15);
backcol = concol((csbi.wAttributes & 0xf0) >> 4);
}
inline void setcolor(concol textcolor, concol backcolor)
{
if (colorprotect && textcolor == backcolor)return;
textcol = textcolor; backcol = backcolor;
unsigned short wAttributes = ((unsigned int)backcol << 4) | (unsigned int)textcol;
SetConsoleTextAttribute(std_con_out, wAttributes);
}
inline void settextcolor(concol textcolor)
{
if (colorprotect && textcolor == backcol)return;
textcol = textcolor;
unsigned short wAttributes = ((unsigned int)backcol << 4) | (unsigned int)textcol;
SetConsoleTextAttribute(std_con_out, wAttributes);
}
inline void setbackcolor(concol backcolor)
{
if (colorprotect && textcol == backcolor)return;
backcol = backcolor;
unsigned short wAttributes = ((unsigned int)backcol << 4) | (unsigned int)textcol;
SetConsoleTextAttribute(std_con_out, wAttributes);
}
inline void concolinit()
{
std_con_out = GetStdHandle(STD_OUTPUT_HANDLE);
update_colors();
deftextcol = textcol; defbackcol = backcol;
}
template<class elem, class traits>
inline std::basic_ostream<elem, traits>& operator<<(std::basic_ostream<elem, traits>& os, concol col)
{
os.flush(); settextcolor(col); return os;
}
template<class elem, class traits>
inline std::basic_istream<elem, traits>& operator>>(std::basic_istream<elem, traits>& is, concol col)
{
std::basic_ostream<elem, traits>* p = is.tie();
if (p != NULL)p->flush();
settextcolor(col);
return is;
}
} //end of namespace eku
#endif //INC_EKU_IO_CONCOL
In concol.h you're defining variables inside a namespace, not declaring them. The variables need to be externed
extern HANDLE std_con_out;
in the header (to define them), then declared (without the extern) in a .cpp file (concol.cpp).
The symbols indicated by the linker as "already defined" are items that are declared in header files, but outside of any class. (In "file scope".) As a result, every .cpp file which includes these header files is trying to redefine storage for them. When the linker tries to link the object files together, it sees these multiple definitions, and it complains about them.
The best thing to do to solve your problem is to make all these items "static data members" of a class. This means declaring them within a class, and marking them as static.
If you do not want to move them inside a class, then you must see to it that they will be declared as "extern" when included by all .cpp files but one. This way, only one .cpp file will try to define storage for them, and the linker will be happy.
This is usually done as follows:
a.cpp:
#define DECLARE_STORAGE
#include "myheader.h"
b.cpp, c.cpp etc:
#include "myheader.h" //without defining DECLARE_STORAGE
myheader.h
#ifdef DECLARE_STORAGE
#define POSSIBLY_EXTERN
#else
#define POSSIBLY_EXTERN extern
#endif
POSSIBLY_EXTERN int my_integer;
this will cause a.cpp to compile the statement
int my_integer;
while b.cpp, c.cpp etc. will compile the statement
extern int my_integer;
I have the following project files:
//connections.cpp
#include "stdafx.h"
#include "LibraryHeaders.h"
#include "FileManager.h"
#define WSAVersion 0x202
#define GSMsgID 0x100
extern HWND Main_hWnd;
bool InitConnections ()
{
FileManager::ConnectFile *connectfile = FileManager::ReadConnectFile(connectfile);
SockBase GSConnection(WSAVersion, TCP, connectfile->GS_IP, connectfile->GS_Port, Main_hWnd, GSMsgID);
if (GSConnection.Connect() != true) {return false;}
return true;
}
//FileManager.cpp
#include "stdafx.h"
#include "FileManager.h"
#include "LibraryHeaders.h"
using namespace FileManager;
ConnectFile* ReadConnectFile(ConnectFile *ConnectStruct)
{
FileLibrary connectfile("DMOConnection.cfg");
if (connectfile.OpenFile(HEAP, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, PAGE_READWRITE) != true) {return false;}
ConnectStruct->GS_IP = connectfile.parser->str_GetToken((char*)connectfile.FileBuff);
if (ConnectStruct->GS_IP == (const char*) -1) {return false;}
ConnectStruct->GS_Port = connectfile.parser->int_GetToken((char*)connectfile.FileBuff);
if (ConnectStruct->GS_Port == -1) {return false;}
return ConnectStruct;
}
//FileManager.h
namespace FileManager
{
struct ConnectFile
{
const char* GS_IP;
unsigned int GS_Port;
};
ConnectFile* ReadConnectFile(ConnectFile*);
}
And when trying to build the project i got this error:
Connections.obj : error LNK2019: unresolved external symbol "struct FileManager::ConnectFile * __cdecl FileManager::ReadConnectFile(struct FileManager::ConnectFile *)" (?ReadConnectFile#FileManager##YAPAUConnectFile#1#PAU21##Z) referenced in function "bool __cdecl InitConnections(void)" (?InitConnections##YA_NXZ)
I dont understand why, the linker should look up and see that ive defined FileManager::ReadConnectFile on FileManager.cpp but it doesnt, any tip how to fix this?
You're defining a free function:
ConnectFile* ReadConnectFile(ConnectFile *ConnectStruct)
not a member:
ConnectFile* FileManager::ReadConnectFile(ConnectFile *ConnectStruct)
Totally different.
Also:
using namespace FileManager;
and
error LNK2019: unresolved external symbol "struct FileManager::ConnectFile [...]
suggests you have a namespace FileManager and a struct FileManager... any reason for using the same name?
i fixed it by declaring the function out of the namespace:
namespace FileManager
{
struct ConnectFile
{
const char* GS_IP;
unsigned int GS_Port;
};
}
using namespace FileManager;
ConnectFile* ReadConnectFile(ConnectFile *ConnectStruct);
The IDE is VC11 Beta, thanks for the answers.
The code
using namespace FileManager;
ConnectFile* ReadConnectFile(ConnectFile *ConnectStruct)
{ ...some definition...}
defines the ReadConnectFile function not in the namespace FileManager, but in global namespace.
I'm having a problem with a vector declaration.
Here's the code:
.h
#ifndef ANIMATEDSPRITE_H_
#define ANIMATEDSPRITE_H_
#include "Sprite.h"
#include <vector>
//using namespace std;
class AnimatedSprite //abstract class to point sprites
{
public:
AnimatedSprite();
~AnimatedSprite();
//gets and sets
Sprite GetMySprite(int _index);
void SetSpriteToList(Sprite _sprite);
int GetState() const;
void SetState(int _state);
//other
private:
std::vector<Sprite> spriteList;
int state; //estado que esse sprite representa (parado esquerda, andando direita, etc)
};
#endif
.cpp
#include "AnimatedSprite.h"
AnimatedSprite::AnimatedSprite()
{
spriteList.clear();
state = NULL;
}
AnimatedSprite::~AnimatedSprite()
{
}
Sprite AnimatedSprite::GetMySprite(int _index)
{
return spriteList[_index];
}
void AnimatedSprite::SetSpriteToList( Sprite _sprite )
{
//Sprite* temp = new Sprite(1,2);
spriteList.push_back(_sprite);
}
int AnimatedSprite::GetState() const
{
return state;
}
void AnimatedSprite::SetState( int _state )
{
state = _state;
}
But I'm getting 2 errors:
Error 1 error LNK2019: unresolved external symbol imp_CrtDbgReportW referenced in function "public: class Sprite & __thiscall std::vector >::operator[](unsigned int)" (??A?$vector#VSprite##V?$allocator#VSprite###std###std##QAEAAVSprite##I#Z) AnimatedSprite.obj
Error 2 fatal error LNK1120: 1 unresolved externals C:\DevProjects\SDLSkeleton\Debug\SDLSkeleton.exe
I've found a solution removing the _DEBUG from the Preprocessor Definitions, but it seems kinda wrong to do that.
Is it the right solution? What's the consequence of removing it?
In the book and documentations I've checked it should be just a common variable declaration, but this errors showed up.
Thanks.
This is because your build is inconsistent: you define _DEBUG macro, but link with release CRT version (/MD). So either remove _DEBUG, or select /MDd option.