error LNK2001 when using a static pointer to another class - c++

I have a two classes. First (Spawn.cpp only prints the message that class was called):
// Spawn.h
#pragma once
#ifndef SPAWN_H_
#define SPAWN_H_
class Spawn {// const + destr only};
#endif /* SPAWN_H_ */
Second:
// Thread.h
#include "Spawn.h"
#pragma once
#ifndef THREAD_H_
#define THREAD_H_
class Thread
{
public:
Thread();
virtual ~Thread();
private:
void Initialise();
static int WindowThread(void *ptr);
static int ConsoleThread(void *ptr);
static Spawn * CreateSpawner();
static Spawn * pSpawner; // if the pointer is non-static, it can't be
// used within static function.
SDL_Thread * pConsoleThread;
};
Spawn * Thread::pSpawner = nullptr;
#endif /* THREAD_H_ */
The code itself:
// Thread.cpp
#include "stdafx.h"
#include "Thread.h"
Thread::Thread() { Initialise(); }
void Thread::Initialise() { // call of the threads here }
int Thread::WindowThread(void * ptr)
{
while (true)
{
// I want to access pointer pSpawner here
}
return 1;
}
int Thread::ConsoleThread(void * ptr)
{
// Main console loop
while (true)
{
/* Spawn handling */
if (CUI.INP == "spawn")
{
pSpawner = CreateSpawner(); // I am unable to access that
// pointer here as well
}
}
return 2;
}
Spawn * Thread::CreateSpawner()
{
// Singleton initialisation:
Spawn * m_pSPAWNER = new Spawn;
return m_pSPAWNER;
}
I am using the SDL external library to create two threads, these threads are static int functions, so it's possible to use only static pointer (if I use a standard pointer the error is that the pointer must be static), but the error I get using Visual studio 2015:
Error LNK2001 unresolved external symbol "private: static class Spawn * Thread::pSpawner"
Error LNK1120 1 unresolved externals
I have tried the suggestions done here, but no result (you can find declaration and definition in the Thread.h):
error LNK2001: unresolved external symbol public: static class
C++ vector issue - 'LNK2001: unresolved external symbol private: static...'
The answers from this question didn't helped (I will leave an update here when I will try all of the suggestions):
What is an undefined reference/unresolved external symbol error and how do I fix it?

This error message is pretty clear, you fail to define your global. It's better to define a global in a cpp file. Because with header he can be define each time you include the header.
// Thread.cpp
Spawn * Thread::pSpawner = nullptr;
It's useless to use #pragma once and #ifndef. Do only one of them.
#pragma once
By the way if you use #ifndef ALL must be inside the #if. You have included "Spawn.h" outside, its can produce an infinite loop of include.
"There is no advantage to use of both the #include guard idiom and #pragma once in the same file."

Related

LNK2019 Error with nested class in C++

I am new to C++, so I am sorry if this a simple or obvious error. I have been reading a lot other questions and the documentation, but I haven't been able to find a solution yet.
I am trying to add a new class definition to a large existing project. Everything compiles perfectly fine without my additions. However, when I add my code below I get a LNK2019 error on the constructor method (and any additional method). I have noticed adding/referencing properties does not cause this linker error, only the methods. Below is the most simple example that produces the error:
Header:
namespace foo
{
class bar_interface
{
public:
//My code
#ifndef Point_H
#define Point_H
class Point
{
public:
Point(int x, int y);
};
#endif
//existing code
void onStartup();
}
}
Class:
//My code
#ifndef Point_H
#define Point_H
class foo:bar_interface::Point{
public:
Point(int x, int y)
{
};
};
#endif
//existing code
void bar_interface::onStartup()
{
foo::bar_interface::Point p( (int)8, (int)8 );
//continue existing code
}
Error 1 error LNK2019: unresolved external symbol "public: __thiscall
foo::bar_interface::Point::Point(int,int)"
(??0Point#bar_interface#foo##QAE#HH#Z)
referenced in function "public: void __thiscall
foo::bar_interface::onStartup(void)"
(?onStartup#bar_interface#foo##QAEXXZ)
I realize that probably do not need such explicit calls to Point or casting the numbers as ints, but I wanted to make sure I wasn't missing anything obvious (removing them doesnt change the error). I have tried moving the 'Point' class to its own file and defining it outside the 'bar_interface' but within the 'foo' namespace. Removing the #ifndef code creates a C2011 redefinition error. I am at a loss for how to proceed.
Unresolved external means that the definition is missing, that is that the linker cannot find an implementation of the named function.
Somewhere you need:
namespace foo
{
bar_interface::Point::Point(int,int)
{ ... }
}
Remove all your lines from the code above that start from # and the reason of the issue becomes cleaner.

Unresolved external symbol "protected static struct" error despite being defined in a .cpp file

This is my eventhandler.h
#pragma once
#include <queue>
#include <Windows.h>
class EventHandler
{
public:
EventHandler()
{
}
~EventHandler()
{
}
static std::queue<MSG*> Events;
};
I've searched a lot to try and solve my problem and all the answers say to declare the static variable in a c++ file, which I've done
#include "EventHandler.h"
std::queue<MSG*> EventHandler::Events;
but I still get
Error LNK2001 unresolved external symbol "protected: static struct tagMSG * Entity::msg" (?msg#Entity##1PAUtagMSG##A)
and I can't figure out why. Have I missed something?
You also need to place your static in cpp file:
// EventHandler.cpp
std::queue<MSG*> EventHandler::Events;

unresolved external symbol in C++ DLL project

can I just start by saying I appreciate you taking your time to go through my question and attempting to help. However I have already attempted the solution suggested on here and on here and they haven't worked for me.
This is my problem:
I am attempting to create a serial port class as a VS12 DLL project. I have a header file "SerialDll.h" which is included in my c++ source file "SerialDll.cpp". When I try to build the solution in visual studio 2012, i get the errors below:
Error 11 error LNK1120: 1 unresolved externals C:\Sprint 7\SerialDll\Debug\SerialDll.dll 1 1 SerialDll
Error 10 error LNK2001: unresolved external symbol "__declspec(dllimport) private: static void * MySerial::MySerialPort::serial_port_handle" (__imp_?serial_port_handle#MySerialPort#MySerial##0PAXA) C:\Sprint 7\SerialDll\SerialDll\SerialDll.obj SerialDll
When I try implementing John Zwinck's Solution, this is the error i get:
Error 2 error C2491: 'MySerial::MySerialPort::serial_port_handle' : definition of dllimport static data member not allowed c:\sprint 7\serialdll\serialdll\serialdll.cpp 16 1 SerialDll
This is the code in my header file:
#include <Windows.h>
#ifdef SERIAL_DLL_EXPORTS
#define SERIAL_DLL_API __declspec(dllexport)
#else
#define SERIAL_DLL_API __declspec(dllimport)
#endif
namespace MySerial
{
class MySerialPort
{
private:
static SERIAL_DLL_API HANDLE serial_port_handle;
public:
SERIAL_DLL_API MySerialPort();
SERIAL_DLL_API ~MySerialPort();
};
}
This is the code in my c++ source file, with John Zwinck's solution:
#include "stdafx.h"
#include "SerialDll.h"
#include <stdexcept>
#include <iostream>
using namespace std;
namespace MySerial
{
HANDLE MySerialPort::serial_port_handle;
MySerialPort::MySerialPort()
{
serial_port_handle = INVALID_HANDLE_VALUE;
}
MySerialPort::~MySerialPort()
{
if(serial_port_handle != INVALID_HANDLE_VALUE)
{
CloseHandle(serial_port_handle);
}
serial_port_handle = INVALID_HANDLE_VALUE;
}
}
Hope you guys can help me with a solution or at least refer me to a link with a working solution.
Cheers!
The answer is exactly the same as this answer to the previous question you linked:
https://stackoverflow.com/a/17902142/4323
That is, you have only declared, but not allocated storage for, your static member. You need to add this to your implementation file:
namespace MySerial
{
HANDLE MySerialPort::serial_port_handle;
}
If you are looking to export the class outside the DLL, then you need to use __declspec for the class, and not for each member function/variable. (See http://msdn.microsoft.com/en-us//library/a90k134d.aspx )
Your header file needs to look like :
namespace MySerial
{
class SERIAL_DLL_API MySerialPort
{
private:
static HANDLE serial_port_handle;
public:
MySerialPort();
~MySerialPort();
};
}

C++ error LNK2001 issue

I am fairly new to cpp but have been in c# for a while. I am trying to run a simple console application but I receive this LNK2001 error message.
I have the main.cpp, and have added another class, Zeus, with files, Zeus.h and Zeus.cpp.
Here is the main.cpp:
#include "Zeus.h"
#include <iostream>
int main()
{
Zeus::tick = 25.0;
using std::cout;
cout << "nothing";
}
Here is the Zeus.h:
static class Zeus
{
public:
static void testing(void);
public:
static double tick;
};
And here is the Zeus.cpp:
void Zeus::testing(void)
{
//Doesnt get this far
//But eventually something like
// cout << "test " << Zeus::tick;
}
And here is the error message:
Error 20 error LNK2001: unresolved external symbol "public: static double Zeus::tick"
Thanks,
You need to define Zeus::tick, typically you would to that in the in the Zeus.cpp file. You have only declared it.
double Zeus::tick = 0.0;
Also, there is no static class in C++.
As an aside, free functions can be put in namespaces, as opposed to being static functions of classes. This is the preferred way in C++, unless there are strong reasons for the function to be static.
namespace Dionysus {
void testing();
}
As the error message says: there's no definition of Zeus::tick. Add this to Zeus.cpp:
double Zeus::tick;
Oh, and in Zeus.h remove the static from
static class Zeus
In the main() function you have, what do you mean by a statement Zeus::tick = 25.0;?
Zeus is a class. So to access the individual elements of it you need to create its instance. Its just like a structure where you first create its instance to access its individual elements.
Try the following:
int main() {
Zeus myobject;
myobject.tick = 25.0;
/* Rest of the definition */
}

How to trace MFC Serialize calls with Macros

I got a MFC app that is writing a huge hierarichy of objects to disk.
To make sense of what is being written I thought of logging all the calls to archive << via stream insertion and .write method by replacing those with macros
#pragma once
#ifndef LOGMAGIC
#define LOGMAGIC
class LogTab
{
public:
static int LogIndentCount;
LogTab()
{
LogIndentCount++;
}
~LogTab()
{
LogIndentCount--;
}
};
#define ARINSERT(AR,OBJ) TRACE( "%*s %s\n", LogTab::LogIndentCount, #OBJ); AR << OBJ;
#define ARWRITE(AR,OBJ,SIZE) TRACE("%*s %s\n", LogTab::LogIndentCount, #OBJ); AR.write(OBJ, SIZE);
#endif
So I created above snippet of code and put it in stdafx.h but I'm getting the following error:
Error 1 error LNK2001: unresolved external symbol "public: static int
LogTab::LogIndentCount" (?LogIndentCount#LogTab##2HA)
What am I doing wrong?
Is there a better way to achieve what I am doing?
You have to define LogTab::LogIndentCount in any one of the .cpp files as,
#include"LogTab.h"
//...
int LogTab::LogIndentCount = 0;
[As a side note, if it's a multi threaded system which is using this class then you may think of making LogIndentCount synchronized (thread safe)]
A static variable must be explicitly initialized.