LNK2019: "Unresolved external symbol" with rapidjson - c++

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)

Related

Typedef function inside a class

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;
};

C++ Setting member object which has const member

I am using OIS for handling my input with Ogre and currently, on KeyPress/Release a Message object like the following will be constructed and distributed among subscribers.
class Message
{
public:
Message();
~Message();
inline void SetKeyEvent(const OIS::KeyEvent& keyEvent) { _keyEvent = keyEvent; }
const OIS::KeyEvent& GetKeyEvent() const { return _keyEvent; }
private:
OIS::KeyEvent _keyEvent;
};
Since this object will be constructed/destroyed whenever input is received via keyboard, I am trying to store a pre-constructed Message object and then simply update the _keyEvent field with the new data, before distributing.
The problem is that the OIS::KeyEvent object has a const member which is preventing me from using the assignment operator. The SetKeyEvent method gives me the following syntax error:
function "OIS::KeyEvent::operator=(const OIS::KeyEvent &)" (declared implicitly) cannot be referenced -- it is a deleted function
I was wondering what the best way to achieve this functionality would be?
Thanks in advance
EDIT: Just to clarify, I already use initializer lists when possible. My intention is to have the Message object pre-constructed and then update the _keyEvent field with the new event data from the KeyPress event which OIS fires, using the SetKeyEvent method. I would like to know if this is possible and if so, what the best way to do it would be.
The copy operator is deleted, so you must work with pointers.
class Message
{
public:
Message();
~Message();
inline void SetKeyEvent(OIS::KeyEvent* keyEvent) { _keyEvent = keyEvent; }
const OIS::KeyEvent& GetKeyEvent() const { return _keyEvent; }
private:
OIS::KeyEvent* _keyEvent;
};
And now it's better to check if the argument in the setter isn't nullptr.
inline void SetKeyEvent(OIS::KeyEvent* keyEvent)
{
assert(keyEvent != nullptr);
_keyEvent = keyEvent;
}
assert() needs #include <assert.h>
EDIT:
Sorry, forgot the getter method. You must use pointers, too.
const OIS::KeyEvent* keyEvent = &Message.GetKeyEvent();
Where Message is your class instance.
It is possible by using placement new and an explicit destructor call, things you normally should never do:
inline void SetKeyEvent(const OIS::KeyEvent& keyEvent)
{
_keyEvent.~KeyEvent();
new (&_keyEvent) OIS::KeyEvent(keyEvent);
}
This is bad ugly horrible code, use at your own risk.

Call virtual function from another subclass

I've been set an assignment to create an rpn calculator that takes infix notation as input. So part of it is that it has to print out different stages of the process. So first it should separate a string into tokens and then store in a vector. Then it should convert this to rpn notation (e.g 3+4 -> 3 4 +) which is the part im stuck on now the part I'm stuck on now.
I've been recommended to use virtual abstract functions for this. So first I create a class with the abstract function. Then I create a subclass which converts a string to tokens stored in a string vector, this part works fine. Then I should create another subclass which converts the input string to rpn notation, therefore I have to call the function to convert to tokens at the start of this sub-class, this is the bit which I think is going wrong.
I have been given some code as a template and so far it's been very buggy so there might be something wrong with the syntax where the error is.
So I have this as my main class
template<typename T>
class tokenstream {
public:
virtual bool process(const std::string& input, std::vector<T>& output) = 0;
};
Then this as the first subclass
class tokenifier: public tokenstream<std::string> {
public:
bool process(const std::string& input, std::vector<std::string>& output) {
//this part works fine, ive tested it.
};
So then I have to create another subclass and then call the above function inside it, this is the part where it goes wrong.
class infix2rpn: public tokenstream<std::string> {
private:
tokenifier *tokens;
public:
tokenifier(tokenstream *_tokens): tokens(_tokens) {} //I think this line is the problem
bool process(const std::string& input, std::vector<std::string>& output) {
//call the underlying tokenstream object
std::vector<std::string> infixtokens;
if(!tokens->process(input, infixtokens))
{
return false;
}
return shunting_yard(infixtokens, output);
}
bool shunting_yard(const std::vector<std::string>& input, std::vector<std::string>& output){
//i've tested the shunting_yard algorithm and it works fine
}
};
When I try to compile it I get the error "ISO C++ forbids declaration of 'tokenifier' with no type [-fpermissive].
So the part I don't understand is how to call other virtual functions from another subclass.
Thanks
Your class is called infix2rpn, so its constructor should be named infix2rpn as well, not tokenifier. This has nothing to do with virtual functions.
Moreover, your attribute should be a tokenstream<std::string>*, not a tokenifier*, because you can't convert the tokenstream<std::string>* you get in the constructor to a tokenifier*.
tokenifier(tokenstream *_tokens): tokens(_tokens) {}
This was probably meant to be constructor, but in that case, the name of the method should be infix2rpn, same as the class name.
The error means, that you specified method tokenifier that has not specified return type, only constructors and destructors have no return type.
Note that void also specification of return type, in that case it means nothing returned.

C++ Hiding a Variable through Inheritance?

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

unresolved externals c++, default constructor

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.