I am working on a VS2010C++ console application, and have created a Manager class that holds static, and dynamic objects of the same type (Thing) one of which being a vector.
I originally got an error on the constructor of the manager class stating that the class it was composed of had no default constructor (but it shouldn't have a default constructor because the objects need to be instantiated at run time, and with run time entered information) I ended up creating a default constructor for the held class (that does nothing), and then I was able to continue after that.
then I got done with all the functionality I need for the program, and I get a whole bunch of LNK2019 "something about unresolved external symbol MethodA referenced in functionB.
first why do I need a default constructor for the managed class if I need it to be done at run-time?
second how do I get rid of these LNK2019? (all of these methods are marked inline in the headers, and its only references to, or from the manager class, and there are no naming conflicts.) as a small note could it have something to do with having to mix access modifiers of . (for the static members), and -> (for the dynamic members)?
Edit:
was able to get rid of the default constructor by limiting its need to a single method, and modifying the other statics to dynamic
for the linker error: in Thing.h
class Thing{
public : int ** Array;
public : int size;
public : Point pi;
public : SinglyLinkedList * moves;
...
public :inline bool operator==(const Thing * _thing);
...
};
Thing.cpp
bool Thing::operator==(const Thing * _Thing){
for(int ii = 0; ii < m; ii++){
for(int jj = 0; jj < m; jj++){
if(Array[ii][jj] != _Thing->Array[ii][jj]){
return false;
}
}
}
return true;
}
ThingMgr.h
class ThingMgr {
public : Thing * control;
public : Thing * Current;
public : Thing * previous;
public : int size;
main.cpp
int _tmain{
...
ThingMgr * TestTings= new ThingMgr(num);
...
if(testThings->control->operator==(testThings->Current)){ // pretty sure its here as it is not called anywhere else in the function.
...
}
error
1>Project_1.obj : error LNK2019: unresolved external symbol "public: bool __thiscall Thing::operator==(class Thing const *)" (??8Board##QAE_NPBV0##Z) referenced in function _wmain
I thought it might have been needing to put parentheses in, but then VS yelled about expecting a member. there are other functions, but maybe if I can figure out what is going on here then those should be fixable.
It would help to see the code. From the sounds of it, you create a std::vector<T> with you type which is given some non-zero size: the std::vector<T> needs to initialize the objects and you apparently didn't give it an object it could copy. You might want to create an empty std::vector<T> and use push_back() your readily constructed objects (or emplace() them if you have a C++2011 system)
With respect to link errors: you apparently didn't define some of the functions you are using. What these are exactly is impossible to tell with the vague description you have given. You'd need to provide more details e.g. the exact link error together with the assumed implementation.
Related
We are supposed to declare the private member variable trackerCoordinates as an atomic.
The .h was originally written like:
class Missile : public Attack, public Sea::Coordinates {
private:
bool hit = false;
Sea::FCoordinates trackerCoordinates;
I've tried to use the std::atomic like this:
class Missile : public Attack, public Sea::Coordinates {
private:
bool hit = false;
std::atomic<Sea::FCoordinates> trackerCoordinates;
Now, in the accompanying .cpp, in line 3, there's a new error, which gets resolved by undoing the std::atomic declaration.
Missile::Missile(Coordinates const & coordinates)
: Coordinates(coordinates),
trackerCoordinates(-1.f,-1.f) -- this line
{
}
The error says:
No matching constructor for initialization of 'std::atomicSea::FCoordinates' (aka 'atomic<TCoordinates>')
I do not know why that error happens and how to resolve it.
A bit more information: FCoordinates is a typedef of TCoordinates, which is supposed
to create coordinates given as a parameter like (x,y), and the TCoordinates constructor is noexcept declared.
Thanks in Advance for any help.
I am writing an app with optional runtime dependency with KWallet. It means if there is KWallet installed on user system it's used and if not it still works but without KWallet support.
Here is how I load the library, it's a static property of my wrapper class. Then in the constructor under condition of state I resolve symbols from the library.
QLibrary Core::PSE::KWallet::lib("KF5Wallet");
...
lib.load();
openWallet = (OpenWallet) lib.resolve("_ZN7KWallet6Wallet10openWalletERK7QStringyNS0_8OpenTypeE");
networkWallet = (NetworkWallet) lib.resolve("_ZN7KWallet6Wallet13NetworkWalletEv");
destructor = (Destructor) lib.resolve("_ZN7KWallet6WalletD2Ev");
The same as the QLibrary - function are also static members of my class, but I'm not sure if that's a good idea.
Here are definitions from my class
typedef ::KWallet::Wallet* (*OpenWallet)(const QString &, WId, ::KWallet::Wallet::OpenType);
typedef QString (*NetworkWallet)();
typedef void (*WalletOpened)(bool);
typedef void (*Destructor)();
static OpenWallet openWallet;
static NetworkWallet networkWallet;
static Destructor destructor;
Here is how I allocate an object
wallet = openWallet(networkWallet(), 0, ::KWallet::Wallet::Asynchronous);
Everything goes fine until the point I need to execute non static members and, especially, destructor. As far as I know, it is supposed to look like that
((*wallet).(destructor))()
but that doesn't seem to work. I'm totally new to this topic and I have no idea even if I had started in a right way.
So, how do I invoke the destructor of this way loaded class? How do I invoke the rest of it's members? Or shall I better do it in some completely other way?
P.S. I'm aware, there is a DBUS API for KWallet, even some wrapper libraries like qtkeychain, but I want to understand the way of making this kind of dependencies using this example.
I have found the solution.
The idea is to write a small shared library with wrapper functions like that
extern "C" KWallet::Wallet* openWallet(const QString &name, WId w, KWallet::Wallet::OpenType ot = KWallet::Wallet::Synchronous) {
return KWallet::Wallet::openWallet(name, w, ot);
}
extern "C" void deleteWallet(KWallet::Wallet* w) {
w->deleteLater();
}
extern "C" const char* networkWallet() {
return KWallet::Wallet::NetworkWallet().toStdString().c_str();
}
extern "C" int readPassword(KWallet::Wallet* w, const QString &key, QString &value) {
return w->readPassword(key, value);
}
Let's call this little wrapper foo.so. So, then you build this foo.so and target link at build time to the real dependency, KWallet in my case.
Then in the main code you're going to try dynamically load this foo.so, not the KWallet itself. And if the KWallet is absent on the launching machine this foo.so is simply not going to load, that's the trick I had to know!
Then of course you simply resolve symbols like this
QLibrary Core::PSE::KWallet::lib("foo");
...
lib.load();
openWallet = (OpenWallet) lib.resolve("openWallet");
networkWallet = (NetworkWallet) lib.resolve("networkWallet");
deleteWallet = (DeleteWallet) lib.resolve("deleteWallet");
readPassword = (ReadPassword) lib.resolve("readPassword");
And call it like this
wallet = openWallet(networkWallet(), 0, ::KWallet::Wallet::Asynchronous);
...
QString password;
int result = readPassword(wallet, *i, password);
...
deleteWallet(wallet);
Before going into solution I should state that this is very bad idea and I can't see a sensible reason to go this way except if you are using a class from a compiled shared library which you can't edit its source and the class has no alternative virtual interface .
The better way to do this in c++ is to use virtual methods by making a base class containing the functionality you need to use and any subclass in a shared library can override those virtual methods to customize the behaviour .
Now this is the solution to your case :
A non static method of a class has a calling convention of thiscall which means that they are like ordinary functions except they take a pointer to the class instance as the first argument , this is the this pointer ! In fact methods in c++ (non virtual) are syntactic sugar for c functions which operate on a struct
This snippet of code illustrates :
struct somestruct
{
int j;
};
void add(somestruct* this, int i)
{
this->j += i;
}
class someclass
{
public:
void add(int i)
{
j += i;
}
private:
int j;
};
So in your case : for each method declaration add a pointer to the class instance that is the first argument and when you want to call this method on an instance just pass it as the first pointer.
Virtual functions are implemented in two ways :
1 - a vtable inside the class itself like c vtables
2 - a pointer to vtable inside the class so you only have one vtable per class declaration and it's said that this method is better for cache hence it's used by most compilers
I want to to be able to have my typedef function inside a class. But i dont find a way to do that. I need to scan for the address so i cant hardcode it in, therfor i need to sett the address like this SetCursorPosFunction = (_SetCursorPos)(address to function);
example:
class Cursor
{
public:
typedef BOOL(__stdcall *_SetCursorPos) (int X, int Y);
_SetCursorPos SetCursorPosFunction;
};
I want to be able to call the function like this Cursor::SetCursorPosFunction(x,y)
Example of what i mean.
void Function()
{
DWORD_PTR AddressToFunctionSetCourserPos = Find(....);
Cursor::SetCursorPosFunction = (Cursor::_SetCursorPos)(AddressToFunctionSetCourserPos ); //In final version it is going to be in a separate function where i get all the functions i need (This find() function can not be looped or called often, it is going to create lag etc.).
Cursor::SetCursorPosFunction(1, 1);
}
I get the errors:
fatal error LNK1120: 1 unresolved externals
error LNK2001: unresolved external symbol "public: static int (__cdecl* Cursor::SetCursorPosFunction)(int,int)" (?SetCursorPosFunction#Cursor##2P6AHHH#ZEA)
Modifying the function to a static will allow you to use it without have to instantiate a member first as you like:
class Cursor
{
public:
typedef BOOL(__stdcall *_SetCursorPos) (int X, int Y);
static _SetCursorPos SetCursorPosFunction;
};
Cursor::SetCursorPosFunction(x,y) should now work (given you initialize it first).
You also need to initialize the static member in global space. Something like Cursor::_SetCursorPos Cursor::SetCursorPosFunction = nullptr; should work. But be careful to have it in only one translation unit.
If you intended to emulate a member function you should create an instance of the cursor before trying to use it:
Cursor cursor;
cursor.SetCursorPosFunction(x, y);
You can also add a constructor to your class to initialize the pointer:
class Cursor
{
public:
Cursor()
: SetCursorPosFunction((_SetCursorPos) GetProcAddress(...))
{ }
typedef BOOL(__stdcall *_SetCursorPos) (int X, int Y);
const _SetCursorPos SetCursorPosFunction;
};
I have a Visual C++ Project in which I added the rapidjson library, which is tested to be working properly. But when I add a rapidjson::Document type to the nested class is throwing a LNK2019 error when I try to compile. The project is a dynamic library to create a DLL.
This are the definitions in my main.h:
class coreBD {
string conn;
string proxy;
int type;
Document test;
enum dataBases {
Sqlite,
SqlServer,
None
};
string queryBD(string sSQL);
string queryHTTP(string sSQL);
string httpRequest(string url, string proxy);
static string getNow(string format);
static string urlEncode(string url);
static bool startsWith(string source, string with);
public:
enum access {
dbConn,
HTTPProtocol
};
//Nested class
class jsonObj {
string jsonStr;
string message;
Document doc; //HERE IS THE PROBLEM
bool validMsg;
public:
enum response {
FullResponse,
SQLResponse
};
jsonObj(string json);
string getJsonStr(response rType);
string getErrorMsg();
bool isValidResponse();
};
coreBD(string connStr, access connType);
jsonObj query(string sSQL);
void setProxy(string proxy);
};
This is the error:
error LNK1120: 1 unresolved externals
error LNK2019: unresolved external symbol "private: __thiscall rapidjson::GenericValue,class rapidjson::MemoryPoolAllocator >::GenericValue,class rapidjson::MemoryPoolAllocator >(class rapidjson::GenericValue,class rapidjson::MemoryPoolAllocator > const &)" (??0?$GenericValue#U?$UTF8#D#rapidjson##V?$MemoryPoolAllocator#VCrtAllocator#rapidjson###2##rapidjson##AAE#ABV01##Z) referenced in function "public: __thiscall rapidjson::GenericDocument,class rapidjson::MemoryPoolAllocator >::GenericDocument,class rapidjson::MemoryPoolAllocator >(class rapidjson::GenericDocument,class rapidjson::MemoryPoolAllocator > const &)" (??0?$GenericDocument#U?$UTF8#D#rapidjson##V?$MemoryPoolAllocator#VCrtAllocator#rapidjson###2##rapidjson##QAE#ABV01##Z)
The error disappears when I comment the line commented with HERE IS THE PROBLEM in the code. As you can see, the use of the test variable in the coreBD class causes no error. The mere existence of the variable of type rapidjson::Document in the nested class causes de error to show; it doesn't matter if I use it or not.
What could be the problem?
EDIT:
New information gathered.
The problem appears when I use the nested class inside the parent one, but only in the return of a method. In other words: I can create everything with rapidjson::Document type as a member variable, I can create a method in coreBD class with type jsonObj, I can instantiate jsonObj inside that methods, but I cannot return a value of type jsonObj if the class jsonObj has a rapidjson::Document member variable declared.
For example this new created method:
jsonObj coreBD::testOBJ()
{
string json = "{error:null, message:None, errorMessage:MoreNone}";
jsonObj b(json);
return b; //It fails here if I return a nested class with a rapidjson::Document in it. Returning NULL works
}
EDIT:
New question continuing solving this: Perform a copy of Document object of rapidjson
Looking at the error it appears that the function returning the jsonObj is doing some kind of a copy or move construction as a part of returning the value and the underlying classes do not allow this probably by making those constructors private members.
There are classes whose design requires that a copy or assignment is prohibited in order to prevent memory leaks or because the objects are singleton type objects and only one version of the object is allowed.
Looking at this documentation on rapidjson there is a note in the section on Move semantics that may be pertinent. It looks like they are preventing a Copy in order to improve performance.
jsonObj doesn't have copy constructor and it can't have any copy constructor since Document's copy constructor is disabled in rapidjson. Try to hold pointer to document instead, something like this :
class jsonObj {
string jsonStr;
string message;
Document* doc; //HERE IS THE PROBLEM
bool validMsg;
}
Or pass document(jsonObj) from outside to:
jsonObj query(string sSQL);
For example:
query(string sSQL, jsonObj & out_obj)
I'm coding a game engine and I'm trying to make all it's functions sorta hidden and mostly rule-free so when programmers code the game, they don't bother with how or why something needs to be that way or another, and I'm trying to stick to leave it purely as C++ language.
So, for example, I don't want them to:
//Going to create a new object on screen
Object* newObject = gameEngine.gameModels.NewObject(); //I don't want this
Instead, I want them to be able to do this:
//Going to create a new object on screen
Object* newObject = new Object();
newObject->Load("objectName"); //Done!
But for this to work, I need to keep the address of my resource loader so I can call the proper Load function and do the actual loading, and this is what I'm doing:
class BaseModel
{
friend GameEngine;
private:
static ResourceModule* moduleAddress;
};
class Model : public BaseModel
{
public:
void Load(char* assetName)
{
//use moduleAddress as needed
};
};
class GameEngine
{
public:
void Initialize()
{
myBaseModel.moduleAddress = &myResourceModule;
}
private:
ResourceModule myResourceModule;
BaseModel myBaseModel;
};
But I'm getting an unresolved external error for the "static ResourceModule* resourceModuleAddress" line, and I can't get the "friend" keyword to work (it also says the variable is private and can't be accessed).
Any suggestions on how can I accomplish what I'm trying to do, or how can I get this code above working?
Unresolved external error comes from lack of definition of the static member. Solution here: Initializing private static members