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.
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
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 3 years ago.
This problem has been solved before, but I've been looking all over, and none of those explains how to fix this, the situation i'm in. Most of them is about external libraries.
I'm trying to test my code. I've made a test class and that class is trying to access another class by including that class's header file. But when I'm trying to call its function it just gives me an unresolved external symbol error.
This is my current attempt. Here I'm trying to access the other classes's header file to call it's functions.
CardTest.cpp
#include <iostream>
#include "../Header Files/Hand.h"
#include "../Header Files/HandValueCalculator.h"
using namespace std;
HandValueCalculator handValueCalculator;
Hand hand;
void Test() {
bool value = handValueCalculator.DoesHandHaveAce(&hand.cards);
cout << value << endl;
}
HandValueCalculator.h
#ifndef HANDVALUECALCULATOR_H_INCLUDED
#define HANDVALUECALCULATOR_H_INCLUDED
#include <vector>
#include "../Header Files/Card.h"
class HandValueCalculator {
public:
HandValueCalculator();
bool DoesHandHaveAce(std::vector<Card>* cards);
int GetValueWithoutAce(std::vector<Card>* cards);
int GetValueWithAce(std::vector<Card>* cards);
};
#endif // HANDVALUECALCULATOR_H_INCLUDED
HandValueCalculator.cpp
#include "../Header Files/HandValueCalculator.h"
HandValueCalculator::HandValueCalculator() {
}
bool HandValueCalculator::DoesHandHaveAce(std::vector<Card>* cards) {
int i;
for (i = 0; i < cards.size(); i++) {
if (cards.at(i).GetValue() == 11) {
return true;
}
}
return false;
}
int HandValueCalculator::GetValueWithoutAce(std::vector<Card>* cards) {
for (i = 0; i < cards.size(); i++) {
int cardValue = cards.at(i).GetValue()
totalValue = totalValue + cardValue;
}
return 0;
}
int HandValueCalculator::GetValueWithAce(std::vector<Card>* cards) {
return 0;
}
This is the error I'm getting, and I don't think the compiler recognizes that the functions have a body, and because it can't find a body for the declared functions it returns an error like this.
C:\Users\fagel\Documents\Blackjack\Blackjack\CardTest.obj : error LNK2019: unresolved external symbol "public: void __thiscall HandValueCalculator::a(void)" (?a#HandValueCalculator##QAEXXZ) referenced in function "void __cdecl Test(void)" (?Test##YAXXZ)
Your HandValueCalculator does not have a void a(); implementation available to the linker. If the a function is defined, make sure you link with the object file containing the definition.
However, you're most likely the victim of the most vexing parse and think you've declared a to be a variable (somewhere not shown), but you've instead declared a function (without 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 declared the the following class:
#pragma once
#include <stdio.h>
#include <vector>
#include <string>
namespace util
{
class FileReader
{
public:
FileReader();
~FileReader();
bool open(const std::wstring& name);
void close();
bool read(std::vector<char>& buf, __int64 startFrom, int size);
__int64 size() const;
private:
FILE* m_file;
std::wstring m_name;
__int64 m_size;
};
}
And its implementation:
#include "FileReader.hpp"
namespace util
{
bool FileReader::open(const std::wstring& name)
{
if (!name.empty() && (m_name != name))
{
close();
if (_wfopen_s(&m_file, name.c_str(), L"rb") == 0)
{
m_name = name;
// Get the file size
_fseeki64(m_file, 0, SEEK_END);
m_size = _ftelli64(m_file);
rewind(m_file);
}
else
{
m_file = NULL;
}
}
return (m_file != NULL);
}
// ....
}
in a seperate library and use it like this:
FileTransfer.cpp
#include <util/FileReader.hpp>
// .....
if (!m_fileReader.open(m_localFileName)) // std::wstring m_localFileName;
{
::MessageBoxA(NULL, "Failed to open file", "Error", MB_ICONERROR);
stopFileTransmission();
return;
}
in another project. Both projects compile successfully, but the FileTransfer.obj fails to link:
Error 2 error LNK2019: unresolved external symbol "public: bool
__thiscall util::FileReader::open(class std::basic_string,class
std::allocator > const &)"
(?open#FileReader#util##QAE_NABV?$basic_string#GU?$char_traits#G#std##V?$allocator#G#2##std###Z)
referenced in function
__catch$?onRequestDirClicked#FileTransferWindow##AAEXXZ$0 C:\Users\x\Documents\dev\Server\FileTransfer.obj Server
I remember it was working when I used std::string, so I assume it has something todo with std::wstring.
Any idea what could be the issue?
It seems, the problem was that the two projects had different values for the setting
Treat wchar_t as built-in type
Setting it to No (/Zc:wchar_t-) for both projects, solved the linker error. I still don't really know what the consequences will be though.
try using extern "C" to declare the open function.
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.