I know there are many solutions on unresolved static symbols here but I can't really find a solution to this problem.
I'm building a simple game framework as a DLL and I'm linking it with another project in my solution. When Actually it's the project I use for testing which is giving the error above not the framework itself. The code seems correct to me, I'm declaring it as a private parameter in the header file and declaring it before anything in the .cpp file.
I'm using Visual Studio 2015 if it can help somehow.
Input.h file:
class DLLEXPORT Manager{
public:
Manager();
};
class DLLEXPORT Input{
public:
static void Foo();
public:
friend class Manager;
static Manager* m_manager;
};
Input.cpp file
#include "Manager.h"
Manager* Input::m_manager = 0;
Manager::Manager(){
Input::m_manager = this;
}
PS: Sorry for the bad english.
Related
I am trying to build a dll to go along with my program in c++. The dll will be a basic library with a bunch of inheritable classes and general utilities, which can then be used dynamically by multiple other applications that will accompany the final product(A Game). I threw something together, only to find that I am recieving I maddening error. It is the famous "error LNK2019: unresolved external symbol". First off, I already found the solution to this, and here is the link: Unresolved External Symbol- Error in guide?
The chosen answer works. If I put my class into only a header file, it compiles perfectly fine, runs, and is all nice and pretty. However, I want to keep the declaration and implementation separate, and if I try to move the implementation to a separate cpp I receive the LNK2019 error. This is due to some kind of inlining, I just want to know how I can bloody fix it before I start tearing my hair out.
Can anyone help me with this? Here is my class:
Header:
#ifndef MYDLLTESTCLASS_H
#define MYDLLTESTCLASS_H
class __declspec( dllexport ) MyDLLTestClass {
public:
MyDLLTestClass();
void setX( int x );
int getX();
private:
int x;
};
#endif // MYDLLTESTCLASS_H
CPP:
#include "MyDLLTestClass.h"
MyDLLTestClass::MyDLLTestClass() {
}
void MyDLLTestClass::setX( int x ) {
this->x = x;
}
int MyDLLTestClass::getX() {
return x;
}
Separate like above, the code wont compile. But if I throw the declaration and implementation together It works, so if I do this:
#ifndef MYDLLTESTCLASS_H
#define MYDLLTESTCLASS_H
class __declspec( dllexport ) MyDLLTestClass {
public:
MyDLLTestClass();
void setX( int x );
int getX();
private:
int x;
};
MyDLLTestClass::MyDLLTestClass() {
}
void MyDLLTestClass::setX( int x ) {
this->x = x;
}
int MyDLLTestClass::getX() {
return x;
}
#endif // MYDLLTESTCLASS_H
It will work. Again, I WANT the declaration and implementation separate.
Here is the build report when I use separate declaration and implementation.
http://pastebin.com/HMEpeEgn
This was actually far easier to solve than I realized; it turns out the it was a visual studio setting all along. First, you need to add the dll project to your current project(Which will be using it). Then you need to right click on you current project and Follow these two pictures:
And then add your dll, which might just need to be check-marked(Mine was simply missing the checkmark).
After that your project will compile perfectly fine! No need for nasty-ass #ifndef macros like every webpage has attempted to portray(which also didn't work mind you)
I have a problem with passing a object to Qt Plugin and when trying to get its member using const member function i get symbol lookup error. Example:
This is inside Qt application:
class A{
int a,b,c;
};
class B{
public:
const QList<A*>* a() const { return m_a; }
private:
QList<A*>* m_a;
};
class C{
public:
const B* b() const { return m_b; }
private:
B* m_b;
};
This is inside QtPlugin:
plugin.h
#include "a.h"
#include "b.h"
#include "c.h"
//....
plugin.cpp
void Plugin::somefunc(C* c)
{
qDebug() << c->b()->a()->count();
}
If I call from Qt application somefunc() of a plugin I get symbol lookup error:
symbol lookup error ... plugin.so undefined symbol _ZNK5b6a
but if I put B and C class members into public domain it works using:
qDebug() << c->m_b->m_a->count();
Did anyone have similar problem or knows how to solve this? Thanks.
Class members are private by default. B::a() and C::b() are private. To be able to call these member functions from Plugin::somefunc() you need to make them public explicitly.
There are two solutions to this "problem".
Make shared library - make shared library and move code that application and QtPlugin use into that library
Add .h and .cpp of files used to QMake file - header and source files of application used in QtPlugin add to HEADERS and SOURCES directive in .pro file - this is actually static linking
I haven't found similar question on web, and thus putting this answer. Maybe question was fuzzy, sorry about that. Thanks for answer. This answer is for any future reference.
I'm a novice programmer, still in the midst of trying to learn C++ and OOP design basics. The project that I've been working on to teach myself is a C++ game that has multiple classes, files, states, etc. However, I keep running into snags with file organization that range from simply struggling with where to create objects to compile-breaking linker errors.
Here's an example of some of the errors that I've been getting:
1>SMGA.obj : error LNK2005: "class Engine smgaEngine" (?smgaEngine##3VEngine##A) already defined in Engine.obj
1>SplashScreenState.obj : error LNK2005: "class Engine smgaEngine" (?smgaEngine##3VEngine##A) already defined in Engine.obj
1>StateManager.obj : error LNK2005: "class StateManager gameStateManager" (?gameStateManager##3VStateManager##A) already defined in Engine.obj
1>MSVCRTD.lib(cinitexe.obj) : warning LNK4098: defaultlib 'msvcrt.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
I've looked around online and I've seen a lot of ~similar~ problems that involve bad include guards or the inclusion of .cpp files instead of .h files. But I haven't done that in my code, so I'm at a loss.
Now, I'm guessing that the error is telling me that I'm trying to create the smgaEngine object of the Engine class (and the gameStateManager object of the StateManager class) twice, but I'm not sure why...
The thing that stands out about these two objects (smgaEngine and gameStateManager) is that I declared them in their corresponding class' .h files immediately after the class declaration. Could this be the issue? - They're still within the include guards, and I wasn't too sure about where else to put them in my code... Would this sloppy coding be the cause of linker errors?
Here's one of the suspect classes...
#ifndef ENGINE_H
#define ENGINE_H
#include <SDL.h>
#include "Timer.h"
class Engine
{
private:
static const int screenWidth = 480;
static const int screenHeight = 270;
static const int screenBPP = 24;
bool running;
SDL_Surface *mainScreen;
SDL_Event eventHolder;
Timer fpsTimer;
public:
Engine();
~Engine();
void init();
void handleEvents();
void handleLogic();
void handleRender();
void cleanUp();
SDL_Event *getEvent();
SDL_Surface *getMainScreen();
bool isRunning();
void setRunning(bool tempRunning);
} smgaEngine;
#endif
And here's the other one:
#ifndef STATEMANAGER_H
#define STATEMANAGER_H
#include "SplashScreenState.h"
#include <vector>
class GameState;
class StateManager
{
private:
std::vector<GameState*> stateStack;
SplashScreenState *splashState;
public:
StateManager();
~StateManager();
void init();
void changeState( GameState *tempNextState );
void addState( GameState *tempNextState );
void removeState();
//returns the back() element of the stateStack vector..
GameState* getTopState();
void handleEvents();
void handleLogic();
void handleRender();
} gameStateManager;
#endif
I've been trying my best to learn C++ and OOP, but I've really been struggling. It seems that every time I attempt to make clean code with encapsulated classes, I end up with a confusing mess. I'm trying to prevent a high degree of class coupling, but I often end up with either linker errors or a lack of ability to communicate between classes... Is it creation of class instance objects within the header files that is causing these errors or is it something else? And if that is the cause of my linker errors, then where should I be creating these objects?
You have defined two global variables, smgaEngine and gameStateManager in your header files, and you have included those header files in two (or more) source files. So you get multiple definition errors. Include guards don't stop header files being included twice in different source files (how could they?) they stop header files being included twice in the same source file.
You're quite close to the correct answer (at least you have a good understanding of the problem). The right way is this
// header file Engine.h
class Engine
{
};
extern Engine smgaEngine;
// in one source file (say Engine.cpp)
Engine smgaEngine;
What you have now is a declaration in the header file (extern makes it a declaration), but a definition in the source file. You can have as many declarations as you like (as long as they are consistent) but you must have only one definition. So for global variables put declarations in the header file and put a definition in one of the source files.
I am trying to build someone else's code in VS2010. It builds fine in VS2005, but I need to upgrade it.
They have defined a macro as follows in a header:
#include <boost/scoped_ptr.hpp>
#include <boost/utility.hpp>
#include <boost/thread/once.hpp>
#define DEFINE_SINGLETON(name) boost::scoped_ptr<name> Singleton<name>::_instance
template<class T> class Singleton : private boost::noncopyable
{
public:
static T& instance()
{
boost::call_once(init, flag);
return *_instance;
}
static void init()
{
_instance.reset(new T());
}
protected:
Singleton() {}
~Singleton() {}
private:
static boost::scoped_ptr<T> _instance;
static boost::once_flag flag;
};
template<class T> boost::once_flag Singleton<T>::flag = BOOST_ONCE_INIT;
I've managed to get the code to build now, but I am getting lots of linker errors about this macro:
project1.lib(file1.obj) : error LNK2001: unresolved external symbol "private: static class boost::scoped_ptr<class ClassABC> Singleton<class ClassABC>::_instance" (?_instance#?$Singleton#VClassABC####0V?$scoped_ptr#VClassABC###boost##A)
An example of the macro being used (in source file):
#include "singleton.h"
DEFINE_SINGLETON(ClassABC);
I am quite new to Boost and also to templates (sorry), so I cannot fathom why I'm getting these errors when it all linked fine in VS2005. Its worth noting, that in order to do the upgrade we have also had to upgrade our Boost version, so this could be a factor - a few checks already performed:
Header file is included in source file
Boost dir is added to include dirs (under VC++ dirs inproperty pages)
Added boost lib dir to Linker -> General -> Additional library dependencies
For info, I am compiling a Multi-threaded debug dll on Win32.
I have spent most of the day googling to no avail, so any help greatly appreciated!
Many thanks :)
I don't see you used the macro anywhere in the posted code.
You need to use it as:
//add this line after BOOST_ONCE_INIT or before it, or wherever you see fit.
template<class T> DEFINE_SINGLETON(T);
Personally I would prefer this:
template<class T> boost::scoped_ptr<T> Singleton<T>::_instance;
I checked out a post similar to this but the linkage was different the issue was never resolved. The problem with mine is that for some reason the linker is expecting there to be a definition for the base class, but the base class is just a interface. Below is the error in it's entirety
c:\users\numerical25\desktop\intro todirectx\godfiles\gxrendermanager\gxrendermanager\gxrendermanager\gxdx.h(2) : error C2504: 'GXRenderer' : base class undefined
Below is the code that shows how the headers link with one another
GXRenderManager.h
#ifndef GXRM
#define GXRM
#include <windows.h>
#include "GXRenderer.h"
#include "GXDX.h"
#include "GXGL.h"
enum GXDEVICE {
DIRECTX,
OPENGL
};
class GXRenderManager {
public:
static int Ignite(GXDEVICE);
private:
static GXRenderer *renderDevice;
};
#endif
at the top of GxRenderManager, there is GXRenderer , windows, GXDX, GXGL headers. I am assuming by including them all in this document. they all link to one another as if they were all in the same document. correct me if I am wrong cause that's how a view headers. Moving on...
GXRenderer.h
class GXRenderer {
public:
virtual void Render() = 0;
virtual void StartUp() = 0;
};
GXGL.h
class GXGL: public GXRenderer {
public:
void Render();
void StartUp();
};
GXDX.h
class GXDX: public GXRenderer {
public:
void Render();
void StartUp();
};
GXGL.cpp and GXDX.cpp respectively
#include "GXGL.h"
void GXGL::Render()
{
}
void GXGL::StartUp()
{
}
//...Next document
#include "GXDX.h"
void GXDX::Render()
{
}
void GXDX::StartUp()
{
}
Not sure whats going on. I think its how I am linking the documents, I am not sure.
The problem is You need to have #include "GXRenderer.h" at the top of both: GXGL.h and also GXDX.h.
The base type must be defined not just declared before defining a derived type.
By the way, the error is a compiling error not linking error.
Edit: About your class type redefinition:
at the top of every header file you should have #pragma once.
The #pragma once directive specifies that the file will be included at most once by the compiler in a build.
You included them all into GXRenderManager.h, meaning that GXRenderManager.h is OK.
But you forgot to include them all into GXGL.cpp and GXDX.cpp. In these .cpp files GXRenderer class is completely unknown.
There are at least two "schools" of #include strategies. One says that header file must include everything that is needed for its own compilation. That would mean that GXGL.h and GXDX.h must include GXRenderer.h. If you followed that strategy, your GXGL.cpp and GXDX.cpp would be OK as they are now.
Another "school" says that header files must not include each other at all, i.e. all inclusions must be done through .cpp files. At first sight one could guess that your GXGL.h and GXDX.h follow that strategy (since you are not including anything into them), but then your GXRenderManager.h looks completely different.
You need to decide which strategy you are trying to follow and follow it. I'd recommend the first one.
I got an error C2504: 'CView' : base class undefined
where CView is not directly my base class from which I am inheriting.
I am inherting mYClass from MScrollView, "for this matter any class which is not actual Base Class is what the point is to be noted down here"
but the error is the C2504. When I have included it in the header where this problem is arising, this problem is resolved.
#include "stdafx.h"
where stdafx.h has #include which contains all the basic class defined...hope this answer resolves everyone who are facing this issue.