Unresolved Externals - c++

I am working on a simple top down shooter and wanted to move my ships to a separate ShipManager class, where I can manage all of them from a single location. However, upon starting this I get a linker error on my playerShip:
error LNK2001: unresolved external symbol "public: static class Ship * ShipManager::playerShip"
ShipManager.h looks like this:
class Ship;
class ShipManager
{
public:
static Ship* playerShip;
};
I have nothing in the ShipManager .cpp yet. What am I missing? The only other place I use this code is in my game class where I am actually calling ShipManager::playerShip, and I don't get any errors there.
I include "ShipManager.h" in my game.cpp, so it should find it right? I have a feeling I'm forgetting something simple in this class.

Static members have to be defined somewhere. You are declaring playerShip, but not defining it. You need to add somewhere, necessarily and only one cpp file:
Ship* ShipManager::playerShip;

You only declared the static member, you also need to define it in (only)one of your cpp files:
Ship* ShipManager::playerShip;
Good Read:
What is the difference between a definition and a declaration?

Related

Unresolved external when trying to link against a dll

I'm trying to link against a dll that I have all the source for, but I can't get access to a dirt simple class I've created in it without getting LNK2019's.
I made this:
class makeprob
{
public:
makeprob();
~makeprob();
};
with the implementation:
makeprob::makeprob() { }
makeprob::~makeprob() { }
as a nice simple template. Then in my actual project, I have the following:
#include "evil_dll.h"
class PC
{
public:
PC() { };
~PC() { };
static makeprob ProblemCreator;
};
with the implementation:
#include "evil_dll.h"
makeprob PC::ProblemCreator;
When I then try to link against it and construct a makeprob class, I get
LNK2019 unresolved external symbol "public: __thiscall makeprob::makeprob(void)" (??0makeprob##QAE#XZ) referenced in function "void __cdecl `dynamic initializer for 'public: static class makeprob PC::ProblemCreator''(void)" (??__E?ProblemCreator#PC##2Vmakeprob##A##YAXXZ)
I've checked that I'm linking against the lib and I am. From everything I can tell, the dll is a 32 bit dll to go with my 32 bit app. I am already using functions from the dll, but they've been declared with __declspec(dllimport)
I have to admit; I'm all thumbs with this. I have no idea if I'm supposed to do anything specific on the receiver to bring a class across from a dll. This is part of a school test, and part of the instructions tell me I don't need to edit the source code (just use the provided classes). I only created the makeprob class to make the problem simple to post up here.
Any advice would be invaluable! Thank you so much!
Scheff actually answers this in the comments above, just formalizing it for Stack Overflow, but Scheff deserves all the cool-haircut-and-rayban-sunglasses points.
My problem is the class implementation doesn't export the constructor or destructor. My makeprob header file above should read like this:
class makeprob
{
public:
__declspec(dllexport) makeprob();
__declspec(dllexport) ~makeprob();
};
to have access to those. Scheff further suggests using macros for this (which I have found they already exist: systemAPI) instead of writing it out manually.
This doesn't get around my professor telling me I don't need to edit the source, but since all the other functions of the class I'm importing have systemAPI in front of them, and only the constructor and destructor don't, I'm gonna call it an oversight? Unless there is a fancy way to import a class without its constructor/destructor.
Thanks everyone!

LNK2001: unresolved external symbol, when trying to call method of object from another DLL

I have two modules, each with own class and with own object. Each module is compiled to a DLL. I want to make a "cross-DLL" method call, having pointer to the object of another class, but linker doesn't allow to do this (MSVC++ 2008).
More specifically:
there is calledModule.cpp, that has calledClass, and object of this class (calledObject); class has calledMethod, which I want to call; module is compiled to DLL and becomes (surprise!) calledLib.dll.
there is callingModule.cpp, that has callingClass; among other things, the class has the attribute, which is a pointer to the calledObject; module is compiled to DLL callingLib.dll; the pointer on calledObject is set in the constructor.
I'm able to compile the whole code. The trouble comes when the linker starts. I'm getting the following:
moduleCalling.obj : error LNK2001: unresolved external symbol "public: void __thiscall classCalled::methodCalled ..."
I don't use any declspec things, so nothing is exported from the calledLib.dll.
The method that I'm calling (methodCalled) is present in the implementation, its prototype is correctly declared in header. The classCalled is a "basic" class, not inherited from anything.
Moreover, the whole project compiles and working correctly, when I declare methodCalled as a virtual...
I have troubles understanding, why I can't call the method of the object in a "normal" way from another DLL? Why declaring it as a "virtual" helps? Anyone knows? I have some guesses, but expert answer will help a lot to understand this stuff.
P.S.: I'm using MSVC++ 2008.
Thanks!
Update: adding code snippet, which reflects, how the code looks like.
// part of calledLib.dll
// moduleCalled.h
class classCalled {
public:
int methodCalled() { return 1 };
};
// ---------------------------------------------------------------
// part of callingLib.dll
// moduleCalling.h
#include "moduleCalled.h"
class classCalling {
public:
classCalled* ref;
void justSomeMethod();
};
// ---------------------
// moduleCalling.cpp
#include "moduleCalling.h"
void classCalling::justSomeMethod() {
ref = new classCalled();
int a = ref->methodCalled(); // <--- this is not allowed by linker,
// unless methodCalled is made virtual.
}
Linker links pieces of code from various modules. If you have a call from one module to another, linker has to know in which other module the function you're invoking is implemented and substitute the call by the real address. This is a very rough picture, but it's enough to understand what is going on.
In your case the linker has to know that your function is located in calledLib.dll. Therefore you have to link with something that refers to calledLib.dll. This something is called an import library. It's name should be calledLib.lib. In order to generate it you either should write a .def file, but it's difficult for class methods, since class methods names used by linker look very different from what they look like in your C++ code. Or you can use declspecs. It will generate the proper calledLib.lib, which you will have to link with your callingLib.dll.

Link error when adding array to common functions class

I have a common functions class. Basic stuff, just has functions several classes in my project can use. But i am trying to add an array of structs so that several classes can use them for some things. Ive removed this array of structs from another Class (Class 1) and added them to my CommonFunctions class. They are only going to be read.
But Im getting errors:
CommonFunctions.obj : error LNK2005: "struct pup_file * pups" (?pups##3PAUpup_file##A) already defined in Class1.obj
error LNK2005: "struct pup_file * pups" (?pups##3PAUpup_file##A) already defined in Class1.obj
fatal error LNK1169: one or more multiply defined symbols found
Then for every other class in the project (which uses the CommonFunctions class, so all of them really) I get
error LNK2005: "struct pup_file * pups" (?pups##3PAUpup_file##A) already defined in main.obj
Anyone help me with whats going on here?
It looks like you didn't declare the pointer pups (it's not an array) inside the class definition.
If you put it in the header but outside the class, you would get errors like those.
The solution is to make sure that pups is declared inside the CommonFunctions class definition.
After reading your comment on making it a static you probably want to define it as an extern rather than static as static means that everything that includes that definition gets its OWN copy (ie the copy is not shared between all of the files that include it).
Extern means that you will need to define it in a c/cpp file somewhere but you must only define it once and then any compilation unit that includes that extern will use the same structure.
Of course you might actually want each compilation unit to have its own copy of the variable and in which case static is what you want.

Linker Errors - Unresolved external symbol

Howdy. I am working on a C++ assignment for my class. I am almost done but can't seem to figure out these errors:
error LNK2001: unresolved external symbol "public: virtual void __thiscall HasQuarterState::dispense(void)const " (?dispense#HasQuarterState##UBEXXZ) gumball.obj Gumball
error LNK2001: unresolved external symbol "public: virtual void __thiscall SoldState::turnCrank(void)const " (?turnCrank#SoldState##UBEXXZ) gumball.obj Gumball
fatal error LNK1120: 2 unresolved externals C:\School Work\CS 492\Gumball\Debug\Gumball.exe Gumball
I went to MSDN and looked up LNK2001 error, but was provided with an overwhelming amount of info, and am afraid I can't figure out what is wrong given my limited experience with C++ from looking at the MSDN page.
But I do believe that the problems come from the way I have structured my program. My teacher said we may use one .cpp file if we wanted too, but I guess in the end I didn't know enough about Visual Studios/C++ to make this work. Ultimately I ran into some other problems that I had to solve that came from using one .cpp file.
The code/file in question is here: http://codepad.org/LpBeJT2Y
Its a big ole mess but this is what I have done:
Declare a class named GumballMachine (no definition)
Define a class named State (which in turn has a pointer to a GumballMachine)
Defined several other state classes which inherit from State
Define class GumballMachine
Defined several functions that were excluded from the original definitions of the other state classes. This is because these functions relied on defined functions of GumbballMachine and wouldn't work until the GumballMachine functions were defined.
void main()
As far as I can tell (with my limited knowledge of VS/C++), the code looks to be fine. Maybe there is something someone with more experience would catch. Any pointers on how to knock out this problem?
Thanks for the help.
You've declared dispense in HasQuarterState but have not defined it. The function has no body. Likewise with turnCrank in SoldState.
In class SoldState, turnCrank is not defined. Change this:
void turnCrank() const;
To this:
void turnCrank() const { cout << "some implementation" << endl; }
and similarly for the other function.

Static Lib Multiple Definition Link Error

So I'm trying to build a small 3D engine as an exercise on VC++ 8.0. I have a MathLib static lib and a Render static lib that is being linked by my TestBed exe. Right now Render has two classes: Color and DXManager3D. Color includes my Vector.h from MathLib just fine, no problems.
The second I try to include Vector.h in DXManager3D it blows up on me, saying the symbol is defined twice, and the second definition is ignored (warning from lib). I thought maybe including it twice was causing this so as a test I removed Vector.h from Color.h and left it in DXManager3D.h - same problem. I have triple checked to make sure I have everything wrapped in ifndef to protect from this, so I am left scratching my head.
DXManager3D.obj : warning LNK4006: "public: __thiscall Math::Vector::Vector(void)" (??0Vector#Math##QAE#XZ) already defined in Render.obj; second definition ignored
What really confuses me is that when I build the Render.lib separate from TestBed, which should not be linking anything as it is a static lib, right? I still get the multiple symbol definition warnings. If I instantiate a DXManager3D in main my warnings become errors.
Render.lib(DXManager3D.obj) : error LNK2005: "public: __thiscall Math::Vector::Vector(void)" (??0Vector#Math##QAE#XZ) already defined in WinMain.obj
Yes, I have F1'd LNK4006 and LNK2005 and the solutions in the MSDN aren't working for me.
Sorry if this question has been asked before, I couldn't find anything solid to help me out using the search feature.
Thanks!
Is your Vector ctor defined in the header outside the class definition? Make it inline then i.e. change
class Vector {
public:
Vector();
// ...
};
Vector::Vector() {
// ...
}
to
class Vector {
public:
Vector() {}
// ...
};
or use an explicit inline qualification:
class Vector {
public:
Vector();
// ...
};
inline Vector::Vector() {
// ...
}
It looks like you have a linkage issue with your vector class. Based on your information it appears that the class is being linked into any lib which includes the header file. This is internal linkage, and you really want external linkage.
Can you post the contents of Vector.h, or at least the Vector() constructor? That should give us a clue to what is actually going on.
Linkage: http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/cplr020.htm
EDIT
Based on your comment, it appears that you have declared all of the functions in the header file outside the class library. You should put them into a non-header file (Vector.cpp file for instance).
This will give your program the appropriate linkage and you will be able to include Vector.h in both programs.