I am new to Cereal and I am having a hard time understanding how to deserialize a JSON string. Unfortunately, my work firewall restricts me from accessing Google Groups to post on the message board.
I have a class that I can turn into a JSON string but can’t for the life of me take the string and recreate the class. Any help would be appreciated and please be gentle I just got out of school, it is my first job, and I am way out my depth.
This is the error I am getting:
terminate called after throwing an instance of 'cereal::RapidJSONException' what(): rapidjson internal assertion failure: IsObject()
Below is MyClass.hpp class:
#include <cstdio>
#include <iostream>
#include <string>
#include "../cereal/access.hpp"
class MyClass{
Public: //function declarations
template<class Archive> // public serialization (normal)
void serialize(Archive & ar)
{
ar(x, y, z);
}
private: // member variables
string x;
int y;
bool z;
};
Below is my Main.cpp:
#include <../cereal/types/unordered_map.hpp>
#include <../cereal/types/memory.hpp>
#include <../cereal/types/concepts/pair_associative_container.hpp>
#include <../cereal/archives/json.hpp>
#include <../cereal/types/vector.hpp>
#include <iostream>
#include <fstream>
#include "MyClass.hpp"
int main(){
// serialize (this part all works... i think)
{
// create a class object and give it some data
MyClass data("hello", 6, true);
// create a string stream object
std::stringstream os;
// assign the string stream object to the Output Archive
cereal::JSONOutputArchive archive_out(os);
//write data to the output archive
archive_out(CEREAL_NVP( data ));
// write the string stream buffer to a variable
string json_str = os.str();
}
// deserialize
{
// create a string stream object and pass it the string variable holding the JSON archive
std::stringstream is( json_str );
// pass the stream sting object into the input archive **** this is the line of code that generates the error
cereal::JSONInputArchive archive_in( is );
// create a new object of MyClass
MyClass data_new;
// use input archive to write data to my class
archive_in( data_new );
}
}
As per cereal documentation
Some archives in cereal can only safely finish flushing their contents upon their destruction. Make sure, especially for output serialization, that your archive is automatically destroyed when you are finished with it.
So it is imporant to call os.str() outside of serialize block, i.e.
MyClass data("hello", 6, true);
std::stringstream os;
{
cereal::JSONOutputArchive archive_out(os);
archive_out(CEREAL_NVP(data));
}
string json_str = os.str();
cout << json_str << endl;
// deserialize
std::stringstream is(json_str);
MyClass data_new;
{
cereal::JSONInputArchive archive_in(is);
archive_in(data_new);
cout << data_new.y << endl;
}
This is working code. You may want to change it further upon your needs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With