unresolved external symbol in c++ with MS visual studio 9 - c++

My code will be similar to the below code:
class DMLGroup
{
public:
DMLGroup();
~DMLGroup();
void SetName(string name);
private:
string mName;
};
void DMLGroup::SetName(string nm){
mName.assign( nm );
}
int main()
{
string api="API_DML";
DMLGroup * dmlGr = new DMLGroup();
dmlGr->SetName(api.c_str()); //Getting link error with this statement
}
I could able to compile the above code but failed to link using MS visual studio 9 on windows 7 32-bit OS.
Note: I am able to compile, link and run successfully on suselinux-x8664 platform. The problem is only with windows
Please tell me how to resolve this?

The following code compiles & links fine:
#include "stdafx.h"
#include <string>
class DMLGroup
{
public:
DMLGroup() {}
~DMLGroup(){}
void SetName(std::string name);
private:
std::string mName;
};
void DMLGroup::SetName(std::string nm){
mName.assign( nm );
}
int main()
{
std::string api="API_DML";
DMLGroup * dmlGr = new DMLGroup();
dmlGr->SetName(api.c_str()); //Getting link error with this statement
}
What I changed:
#included stdafx.h because it's VS standard - you can turn it off
#includes because it was missing
decorated every use of string with std:: - because most probably you'll use your class definition in a header file and there you simply don't use "using namespace"
supplied default implementation for constructor & destructor
That's all. Check what from the above part is missing or supply an example that exposes the problem & supply the linker error message.

Related

What is causing these 'unexpected tokens' errors after constructor?

I am working on a circuit simulator/pathfinding system, but I keep getting these weird compilation errors. I am not yet that experienced with OO C++ to figure it out myself...
Object Tree
The objects in my project are implemented in this way:
Object
Component
Wire
Switch
Ciruit
My Object class is the base class for everything in my project, this is great for debugging by giving everything a name and an id.
I required that every component needs a Circuit to with (see it as a parent for components). I implemented this by creating a constructor in the Component class that requires a reference to a Circuit object.
At first, everything worked and compiled fine, but when I introduced the Circuit class and when I added a constructor in Component with a Circuit reference parameter, everything went wrong...
Compilation errors
Now I keep getting these seemingly random syntax and missing tokens errors. (Intellisense does not mark them?)
The first four errors that pop up are:
C2238: unexpected token(s) preceding ';'.
At line 10 of Component.hpp. And at line 12 in file Circuit.hpp.
Both just after the constructor definition. (See in code below)
The next four errors point tot the same locations, but it notes:
C2143: syntax error: missing ';' before '*'.
Then, 30 more errors follow, but I think they are a result of these errors, to be sure, here they are:
(Lol, cannot embed image, caused by not having enough reputation, so a link instead...)
Click here for errors
What I tried
I tried the following:
Using a reference instead of pointer. (changed Circuit* c to Circuit& c)
Removing the name string concationation thing in constructor initializer list. (changed ... : Object(name + "blah") to ... : Object(name))
Rewriting the whole Visual Studio project to a new Visual Studio project.
Placing the constructor initializer list in the header file.
Lots of googling... and not lots of solving...
How to fix?
This frustrating problem is stopping me from working further on this project, what is causing it and how do I fix it? I would be pretty happy to know.
Object.hpp
#pragma once
#include <string>
using std::string;
class Object
{
public:
Object();
Object(string name);
string name;
const int id;
virtual string toString();
private:
static int currentId;
};
Object.cpp
#include "Object.hpp"
int Object::currentId = 0;
Object::Object() : id(++Object::currentId), name("Object")
{ }
Object::Object(string name) : id(++Object::currentId), name(name)
{ }
string Object::toString()
{
return name + "#" + std::to_string(id);
}
Component.hpp
#pragma once
#include "Object.hpp"
#include "Circuit.hpp"
class Component : public Object
{
public:
Component(std::string name, Circuit* container);
Circuit *container; // <- Error points to the beginning of this line
};
Component.cpp
#include "Component.hpp"
Component::Component(string name, Circuit* container) : Object(name), container(container)
{ }
Switch.hpp
#pragma once
#include "Component.hpp"
#include "Wire.hpp"
class Switch : public Component
{
public:
Switch(string name, Circuit* container, Wire& wire1, Wire& wire2);
Wire* wire1;
Wire* wire2;
void setEnabled(bool enabled);
bool getEnabled();
private:
bool enabled;
};
Switch.cpp
Switch::Switch(string name, Circuit* container, Wire& wire1, Wire& wire2) : Component(name + "-Switch", container), wire1(&wire1), wire2(&wire2), enabled(false)
{ }
...
Circuit.hpp
#pragma once
#include "Object.hpp"
#include "Wire.hpp"
class Circuit : public Object
{
public:
Circuit(std::string name);
Wire* powerWire; // <- Error points to the beginning of this line
bool isPowered(Wire& wire);
bool getActive();
void setActive(bool active);
private:
bool active;
};
Circuit.cpp
#include "Circuit.hpp"
#include "Util.hpp"
Circuit::Circuit(string name) : Object(name + "-Circuit")
{
active = false;
powerWire = new Wire(name + "-PowerWire", this);
}
...
You haven't shown Wire.hpp, but my guess is that it includes Component.hpp, which gives you a cycle in header inclusion (because Component.hpp includes Circuit.hpp, and Circuit.hpp includes Wire.hpp).
You will have to replace some of these inclusions with forward declarations to break the cycle.

Visual Studio doesn't accept class implementation [C++]

I'm trying to move from Dev C++ to Visual Studio while studying C++ (since I'll have to work with the latter) but for some reason, a rather simple class implementation that perfectly works in Dev C++ creates a long list of errors in Visual Studio.
The files are simple:
header file, for the declaration of constructors, variables etc
cpp file, to implement said constructors, functions etc
consoleapplication file (on visual studio), to produce the "main()" function.
stock2.h
#ifndef STOCK2_H_
#define STOCK2_H_
class Stock
{
public:
Stock();
Stock(const char* co, int n = 0, double pr = 0.0);
~Stock();
void show()const;
private:
std::string company;
int shares;
double share_val;
double total_val;
};
#endif
stock2.cpp
#include "stdafx.h"
#include <iostream>
#include <string>
#include "stock2.h"
Stock::Stock() //default constructor
{
//code
}
Stock::Stock(const char* co, int n, double pr)
{
//code
}
Stock::~Stock()
{
std::cout << "Stock object has been destroyed" << std::endl;
}
//Methods
void Stock::show() const
{
//code
}
ConsoleApplication.cpp
#include "stdafx.h"
#include "stock2.cpp"
int main()
{
using std::cout;
const int STKS = 4;
Stock stocks[STKS] = {
Stock("NanoSmart", 12, 20.1),
Stock("Boffo Objects", 200, 2.0),
Stock(),
Stock("Monolithic Obelisks", 130, 3.25)
};
cout << "Stock Holdings: \n";
for (int st = 0; st<STKS; st++)
stocks[st].show();
return 0;
}
I've tried to find the solution on other questions posted here but I really can't figure out what's wrong here.
I also read that one is not supposed to #include a cpp file since the header should be the link between the main() and the cpp file itself, but if I decide to use #include stock2.H instead of .CPP in consoleapplication, then the compiler can't find the methods implementations anymore.
EDIT: In the rush i forgot to post the errors!
They're all in this form:
Error LNK2005
"public: void __thiscall Stock::update(double)" (?update#Stock##QAEXN#Z) already defined in
ConsoleApplication1.obj ConsoleApplication1 //path\ConsoleApplication1\ConsoleApplication1\stock2.obj
EDIT2: Since many of you are asking me about the "Solution Explorer", I better just add a screenshot to show you how it's made right now
You included stock2.cpp in your ConsoleApplication.cpp. This means all the code inside stock2.cpp is now compiled twice, and the linker shows the error message
Error LNK2005 "public: void __thiscall Stock::<...> already defined
for the now duplicated functions. Simply replace
#include "stock2.cpp"
with
#include "stock2.h"
If you get another error when doing so, please post the error message for this.

Linker errors when calling C++/CLI code from pure C++ code

I am using VS2012 and I am trying to call CLI code from C++. So I created two projects. One is executable which is pure C++ (without CLI support) and second is dynamic library which is CLI (with /clr switch). If I have main (in executable):
// main.cpp file
#include "..\CLILibrary\CCli.h"
int main()
{
Ccli test = Ccli();
test.Write();
return 0;
}
And one class in CLI library (build with CLR switch on):
// Ccli.h file
#pragma once
class Ccli
{
public:
void Write();
void CallRealCLIClass();
};
// Ccli.cpp file
#include " Ccli.h"
void Ccli::Write()
{
System::Console::WriteLine("In Ccli class.");
}
void Ccli::CallRealCLIClass()
{
// here I would like to call RealCLI class
}
Everything works fine so far. I understand, that header file (Ccli.h) cannot use anything from CLI since it has to be readable for my executable which is purely in C++ (theoretically it could if I would use something like #ifdef _MANAGED but thatÆs not my point). But in source file (Ccli.cpp) it is fine.
But now I want to use class which will be fully CLI. And I want to call it from Ccli.cpp file. So I created following class in my CLI library:
// RealCLI.h file
#pragma once
ref class RealCLI
{
public:
RealCLI(void);
System::String^ GetString();
void Write(System::String^ s);
};
// RealCLI.cpp file
#include "RealCLI.h"
RealCLI::RealCLI(void){}
System::String^ GetString()
{
System::String^ s = gcnew System::String("GetString in RealCLI class");
return s;
}
void Write(System::String^ s)
{
System::Console::WriteLine(s);
}
Now I have following problem and I don't know why. I get this error from linker:
Error 1 error LNK2020: unresolved token (06000002) RealCLI::GetString ...\RealCLI\RealCLI.obj
Error 2 error LNK2020: unresolved token (06000003) RealCLI::Write ...\RealCLI\RealCLI.obj
Error 3 error LNK1120: 2 unresolved externals ...\Debug\RealCLI.dll 1
So my library is fine (it is built without problem) but my executable have these linker errors. I don't understand why? I don't use this file in my executable project, so why is my executable even care about it? I find a way how to fix it. But since I don't know the reason why is the original program not working I consider it just as workaround. My workaround is delete RealCLI.cpp file and put everything in header file:
// RealCLI.h file
#pragma once
ref class RealCLI
{
public:
RealCLI(void) {}
// I cannot even put definition outside declaration of my class
System::String^ GetString()
{
System::String^ s = gcnew System::String("GetString in RealCLI class");
return s;
}
void Write(System::String^ s)
{
System::Console::WriteLine(s);
}
};
Why is that? What am I doing wrong? Is some of my assumptions wrong?
EDIT:
// Ccli.cpp file
#include " Ccli.h"
// !!!added this line:
#include "RealCLI.h"
void Ccli::Write()
{
System::Console::WriteLine("In Ccli class.");
}
void Ccli::CallRealCLIClass()
{
// here I would like to call RealCLI class
}
I repaired namespaces in RealCli.cpp which helped. But when I added #include "RealCLI.h" I get these error anyway:
Error 2 error LNK2020: unresolved token (06000001) RealCLI::.ctor D:\ftp\my\vyuka-cppToCLI-test\vyuka-ManagedUmanaged\UnmanagedToManagedSource.obj
Error 3 error LNK2020: unresolved token (06000002) RealCLI::GetString D:\ftp\my\vyuka-cppToCLI-test\vyuka-ManagedUmanaged\UnmanagedToManagedSource.obj
Error 4 error LNK2020: unresolved token (06000003) RealCLI::Write D:\ftp\my\vyuka-cppToCLI-test\vyuka-ManagedUmanaged\UnmanagedToManagedSource.obj
Error 5 error LNK1120: 3 unresolved externals D:\ftp\my\vyuka-cppToCLI-test\Debug\vyuka-ManagedUmanaged.exe 1
You are making basic C++ mistake. In RealCLI.cpp:
Instead of:
System::String^ GetString() { ... }
use:
System::String^ RealCLI::GetString() { ... }
Similarly for Write()
Actually I didn't set linker right. Code is (after edit) Ok. I'm linking to .obj files, because I get errors when linking directly to .dll (because it is not pure C++ but CLI). And I linked just Ccli.obj then few weeks later I add another file and forgot link RealCLI.obj...

Unresolved External Symbol while creating an object

I am trying to run a main.cpp which access 3 different classes. For some reason, I am getting a unresolved external symbol error. From what I've seen online, its clearly a linking error somewhere, but I cannot find it. I've listed the error below, but it's got a lot of info in it and im having trouble finding out exactly what it means.
The error: main.obj:-1: error: LNK2001: unresolved external symbol "public: __thiscall AtpReader::AtpReader(class std::basic_string,class std::allocator >)" (??0AtpReader##QAE#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z)
My code is:
main.cpp:
#include <iostream>
#include "atlasobject.h"
#include "atp.h"
#include "atpreader.h"
using namespace std;
int main()
{
AtpReader reader("E:/doc.txt");
return 0;
}
AtpReader.h:
#ifndef ATPREADER_H
#define ATPREADER_H
#include "atp.h"
class AtpReader
{
public:
AtpReader();
AtpReader(string filename);
void atpReadHeader();
void atpRead();
string decryptLine(string line);
ATP readerATP;
private:
string file;
};
#endif // ATPREADER_H
atp.h:
#ifndef ATP_H
#define ATP_H
#include "atlasobject.h"
#include "vector"
struct Image{
string Dim;
string Vox;
string Ori;
char* data;
};
class ATP
{
public:
ATP();
vector<AtlasObject> listOfMaps;
private:
Image referenceImage;
};
#endif // ATP_H
and AtlasObject.h:
#ifndef ATLASOBJECT_H
#define ATLASOBJECT_H
#include <string>
using namespace std;
class AtlasObject{
public:
//virtual void create();
AtlasObject();
void set_uid(string id);
void set_label(string l);
void set_offset(string o);
void set_mapInfo(string info);
void set_data(char* inData);
void set_isEncrypted(int encrypted);
string get_uid();
string get_label();
string get_offset();
string get_mapInfo();
char* get_data();
int get_isEncrypted();
protected:
string uid;
string label;
string offset;
string mapInfo;
char *data;
int isEncrypted;
};
#endif // ATLASOBJECT_H
my AtpReader.cpp is:
#include "atpreader.h"
#include <iostream>
#include <fstream>
#include <stdint.h>
#include <sstream>
AtpReader::AtpReader()
{
printf("AtpReader()\n");
}
AtpReader::AtpReader(string filename)
{
printf("AtpReader(%s)\n",filename.c_str());
}
I see you did not include AtpReader.h in AtpReader.cpp, but probably you just missed it when you made copy/paste, to insert it here, because if you didn't really include it, the error would have been different. Also, I see you're including in your main.cpp both "atlasobject.h"
and "atp.h" and you don't really need that.
Later edit: Your problem is in the atp.h...you constructor is declared but never defined. Do this: ATP(){};
Try using g++ in linux terminal
make the object files of each of the source codes and then link the object files and run the executable
g++ -c atp.cpp AtpReader.cpp AtlasObject.cpp
g++ -o exe atp.o AtpReader.o AtlasObject.o
./exe
AtpReader.cpp is not getting built or the its object file is not getting linked to final executable. Check if AtpReader.obj/.o is created in build directory.
Because of the linker error you are getting and assuming that this is some of your actual code. Since I can't see any function inlining, global constants or variables being used out of scope I think the problem is located in the AtpReader.cpp, are you missing an #include AtpReader.h there?
With just a function prototype, the compiler can continue without error, but the linker cannot resolve a call to an address because there is no function code or variable space reserved. You will not see this error until you create a call to the function that the linker must resolve.

Duplicate symbols only for iOS simulator build

I'm having a strange issue when compiling an open source library. When compiling for the device, Xcode compiles it just fine and deploys it no problem. However, when I compile for the simulator, I get duplicate symbol errors during the linking phase.
I've checked a few of these out, and it seems these symbols were all implemented in the .hh file as opposed to the .m file. Obviously this is bad code structure, and the errors make sense. However, what doesn't make sense is why there are no errors for the device build.
Each of these .hh files contains #pragma once at the top of the file. My initial thought was that this wasn't working as expected, but upon removal I get compile-time errors for both device and simulator builds stating I've redefined these symbols. Hmm, so I then tried replacing #pragma once with
#ifndef EXAMPLE_DEFINE
#define EXAMPLE_DEFINE
// code
#end if
But this yields identical results to the #pragma once.
Due to the sheer number of code changes that would be required, it isn't feasible for me to go through and fix every error manually, especially since I'll want to be able to update the codebase easily. So is there any reason this is not failing for the device, and how I could make simulator builds perform the same way?
EDIT: I've also tested using #import instead of #include, but it too yields the same results
EDIT 2: After more testing, I've found that if I define a Preprocessor macro in the target's build settings, the code inside the #ifndef never gets called, as is expected. For whatever reason, it looks like defining the new definition in the .hh file isn't being carried over into the next compilation of the file.
Also, as requested, here's an excerpt from the build log
duplicate symbol __ZZN12DelegateFuncIFvR16DualTextMenuItemRKN5Input5EventEEEC1IZN25MultiChoiceSelectMenuItem4initEPPKciiibSB_P12ResourceFaceEUlS1_S5_E_EERKT_PNSt3__19enable_ifIXntsr3std11is_functionISG_EE5valueEvE4typeEENKS8_ISF_EUlRKNS7_7StorageES1_S5_E_cvPFvSR_S1_S5_EEv in:
/Users/riley.testut/Library/Developer/Xcode/DerivedData/GBA4iOS-dqkflotukruucqbxjyslhtfuekse/Build/Intermediates/GBA4iOS.build/Debug-iphonesimulator/GBA4iOS.build/Objects-normal/i386/Main-FB93852047D42061.o
/Users/riley.testut/Library/Developer/Xcode/DerivedData/GBA4iOS-dqkflotukruucqbxjyslhtfuekse/Build/Intermediates/GBA4iOS.build/Debug-iphonesimulator/GBA4iOS.build/Objects-normal/i386/OptionView.o
duplicate symbol __ZZN12DelegateFuncIFbiRKN5Input5EventEEEC1IZN15MultiChoiceView4initER19MultiChoiceMenuItemb9_2DOriginEUliS3_E_EERKT_PNSt3__19enable_ifIXntsr3std11is_functionISC_EE5valueEvE4typeEENKS6_ISB_EUlRKNS5_7StorageEiS3_E_cvPFbSN_iS3_EEv in:
/Users/riley.testut/Library/Developer/Xcode/DerivedData/GBA4iOS-dqkflotukruucqbxjyslhtfuekse/Build/Intermediates/GBA4iOS.build/Debug-iphonesimulator/GBA4iOS.build/Objects-normal/i386/Main-FB93852047D42061.o
/Users/riley.testut/Library/Developer/Xcode/DerivedData/GBA4iOS-dqkflotukruucqbxjyslhtfuekse/Build/Intermediates/GBA4iOS.build/Debug-iphonesimulator/GBA4iOS.build/Objects-normal/i386/OptionView.o
duplicate symbol __ZZN12DelegateFuncIFvR12TextMenuItemRKN5Input5EventEEEC1IN14YesNoAlertView2noMUlS1_S5_E_EEERKT_PNSt3__19enable_ifIXntsr3std11is_functionISB_EE5valueEvE4typeEENKS8_ISA_EUlRKNS7_7StorageES1_S5_E_cvPFvSM_S1_S5_EEv in:
/Users/riley.testut/Library/Developer/Xcode/DerivedData/GBA4iOS-dqkflotukruucqbxjyslhtfuekse/Build/Intermediates/GBA4iOS.build/Debug-iphonesimulator/GBA4iOS.build/Objects-normal/i386/ButtonConfigView.o
/Users/riley.testut/Library/Developer/Xcode/DerivedData/GBA4iOS-dqkflotukruucqbxjyslhtfuekse/Build/Intermediates/GBA4iOS.build/Debug-iphonesimulator/GBA4iOS.build/Objects-normal/i386/MenuView.o
ld: 16 duplicate symbols for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
and here's one of the offending files (AlertView.hh):
#pragma once
#include <gui/View.hh>
#include <gui/MenuItem/MenuItem.hh>
#include <util/gui/BaseMenuView.hh>
#include <util/rectangle2.h>
#include <util/DelegateFunc.hh>
class AlertView : public View
{
public:
constexpr AlertView() { }
Rect2<GC> labelFrame;
Gfx::Text text;
BaseMenuView menu;
Rect2<int> rect;
Rect2<int> &viewRect() { return rect; }
void init(const char *label, MenuItem **menuItem, bool highlightFirst);
void deinit() override;
void place() override;
void inputEvent(const Input::Event &e) override;
void draw(Gfx::FrameTimeBase frameTime) override;
};
class YesNoAlertView : public AlertView
{
public:
YesNoAlertView() { }
typedef DelegateFunc<void (const Input::Event &e)> InputDelegate;
MenuItem *menuItem[2] = {nullptr};
// Optional delegates
InputDelegate &onYes() { return onYesD; }
InputDelegate &onNo() { return onNoD; }
void init(const char *label, bool highlightFirst, const char *choice1 = nullptr, const char *choice2 = nullptr)
{
yes.init(choice1 ? choice1 : "Yes"); menuItem[0] = &yes;
no.init(choice2 ? choice2 : "No"); menuItem[1] = &no;
assert(!onYesD);
assert(!onNoD);
AlertView::init(label, menuItem, highlightFirst);
}
void deinit() override
{
logMsg("deinit alert");
AlertView::deinit();
onYesD = {};
onNoD = {};
}
InputDelegate onYesD;
InputDelegate onNoD;
private:
TextMenuItem yes
{
[this](TextMenuItem &, const Input::Event &e)
{
auto callback = onYesD;
removeModalView();
if(callback) callback(e);
}
};
TextMenuItem no
{
[this](TextMenuItem &, const Input::Event &e)
{
auto callback = onNoD;
removeModalView();
if(callback) callback(e);
}
};
};
It shows you have tried the header guards but my suggestion is once you check for following
link.
http://en.wikipedia.org/wiki/Include_guard
http://c2.com/cgi/wiki?RedundantIncludeGuards
The update shows it is linker error for symbols and this is for the library you are using.